SitePoint Sponsor

User Tag List

Results 1 to 5 of 5
  1. #1
    SitePoint Addict bronze trophy Hall of Famer's Avatar
    Join Date
    Apr 2013
    Location
    Ithaca
    Posts
    368
    Mentioned
    6 Post(s)
    Tagged
    2 Thread(s)

    Is it considered Anemic Domain Model Anti-pattern if...

    a data object is stored inside the domain model? Like this sample script provided?

    PHP Code:
    class User extends DomainModel{
        protected 
    $id = -1// a primary key
        
    protected $data// stores basic data for user in primitive type format
        
    protected $profile// a proxy field for user profile object
        
    protected $validator// a user validator reference
        
    protected $mapper// a user mapper reference

        
    public function __construct(UserData $data NULL){
            if(
    $data){
                
    $this->id $data->getID();
                
    $this->data $data;  
            } 
        }

        public function 
    getID(){
            return 
    $this->id;
        }

        public function 
    getUserName(){
            return 
    $this->data->getUserName();
        }

        public function 
    setUserName($username){
            
    $this->data->setUserName($username);
        }

        public function 
    getPassword(){
            return 
    $this->data->getPassword();
        }

        public function 
    setPassword($password){
            
    $this->data->setPassword($password);
        }

        public function 
    getEmail(){
            return 
    $this->data->getEmail();
        }

        public function 
    setPassword($email){
            
    $this->data->setEmail($email);
        }

        public function 
    getProfile(){
            if(!
    $this->profile){
                
    $this->getMapper();
                
    $profileMapper $this->mapper->getProfileMapper();
                
    $this->profile $profileMapper->findByID($this->id);
            }
            return 
    $this->profile;
        }

        public function 
    getMapper(){
            if(!
    $this->mapper$this->mapper = new UserMapper
            return 
    $this->mapper;
        }

        public function 
    getValidator(){
            if(!
    $this->validator$this->validator = new UserValidator;
            return 
    $this->validator;
        }

        public function 
    setValidator(UserValidator $validator){
            
    $this->validator $validator;
        }

        public function 
    validate(){
            
    $this->getValidator();
            return 
    $this->validator->validate();
        }
       
        
    // other domain logic goes below

    So the domain model class does have business logic in it, it can validate, calculate and even act as factory for other models that has one to one or one to many dependency on it(a userprofile model to a user model is a good one). However, its data is encapsulated inside a data object, which has only protected fields and public getter/setter methods. My question is, is this design considered anemic domain model anti-pattern? Its a bit tricky here though, 'cause the domain model itself does not look like an anemic domain model, but if you look at the data object it does not have domain logic. I am actually still a bit confused at what the precise definition for anemic domain model is. Anyone mind elaborating this a bit and Id like to know if this kind of domain model in which the data fields are stored in a data object is considered an anti-pattern. Thx.

  2. #2
    SitePoint Addict bronze trophy Hall of Famer's Avatar
    Join Date
    Apr 2013
    Location
    Ithaca
    Posts
    368
    Mentioned
    6 Post(s)
    Tagged
    2 Thread(s)
    umm no one knows the answer? Is this question too complex?

  3. #3
    SitePoint Member
    Join Date
    Feb 2009
    Posts
    17
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I think it is more that it is very subjective and not really related to models but just general design.

    1. Moving clumps of related data into an object is good (http://sourcemaking.com/refactoring/data-clumps)
    2. Using delegation instead of passing the object straight out in an accessor can also be viewed as good.
    http://sourcemaking.com/refactoring/hide-delegate
    Though there is an inverse refactoring called remove middle man
    http://sourcemaking.com/refactoring/remove-middle-man

    The way to look at it is the design of software is both reactive and opportunistic, you try and put behaviour
    in the best place behaviour can go. Primitives block this which is why primitive obsession is viewed as not and
    ideal practice (http://sourcemaking.com/refactoring/primitive-obsession). They block the balanced spread of behaviour
    that would of naturally occured while doing iterative design.

    For example having a UserData class instead of primitives allows the opportunity of adding behaviour to the UserData class
    instead of being forced into the user Model such as instantiating a UserData variant that can be viewed as
    equivelent to Null similar to a NullObject( http://sourcemaking.com/refactoring/...ce-null-object ). This
    is more about how you want it to fail if the $user->getID() != -1 check is not done externally prior to accessing
    the getUserName method as should it really possibly fatal, if it should be fatal would an
    exception with a stacktrace be better?

    eg. using the override method technique to trigger exceptions
    PHP Code:
    class InvalidUserData extends UserData {
        
        public function 
    getPassword(){
            throw new 
    BadMethodCallException();
        }

    It is a big topic from just a little bit of code.

  4. #4
    SitePoint Addict bronze trophy Hall of Famer's Avatar
    Join Date
    Apr 2013
    Location
    Ithaca
    Posts
    368
    Mentioned
    6 Post(s)
    Tagged
    2 Thread(s)
    Thanks for your input. I am not sure if you really were answering the exact question I was asking, but the details you provided such as NullObject were really interesting and practical.

  5. #5
    SitePoint Member
    Join Date
    Feb 2009
    Posts
    17
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Well all those articles are actually from the Refactoring book by Martin Fowler who is often referenced on things like the AnemicDomainModel(http://martinfowler.com/bliki/AnemicDomainModel.html) by other authors so the question really is would he not use the techniques he has made of lot off of promoting when creating/modifying a domain model, basically is the domain model so different from any other piece of code it is exempt from following those practices. I personally believe it does not and I don't think he would either judging from everything I have read, especially when doing TDD as if you were not allowed to inject any behaviour into a domain model you would end up with something very fat to test( such as UserData->setId could actually handle int validation and throw an exception etc if it was not satisfied and be tested in isolation ).

    What denotes the behaviour of the class is the external contract ( public or protected methods ) not the internal implementation so if a model has the public/protected methods to achieve the end result it is achieving the end result, the external consumer of the model doesn't really care as all it is concerned with is that it does not have to do the work the model should in the end be doing. If the model is not doing enough then feature envy (http://sourcemaking.com/refactoring/feature-envy) may become apparent.

    Basically I think what indicates an Anemic Domain Model is not how it is composed but what type of interactions it forces when consumed throughout a project.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •