What methods should go in my DDD factory class?

后端 未结 7 1396
终归单人心
终归单人心 2021-02-02 17:38

I am struggling to understand what my factory class should do in my DDD project. Yes a factory should be used for creating objects, but what exactly should it be doing. Consid

7条回答
  •  有刺的猬
    2021-02-02 18:15

    In the builder you can have any logic you need to inforce the invariants on your entites, a little example using Java as development language...

    I have a User entity that has a username, a password and an email, all attributes required so I have:

    public class User {
        private String username;
        private String password;
        private String email:
    
        /**
         * @throws IllegalArgumentException if the username is null, the password is null or the
         * email is null.
         */
        public User(final String theUsername, final String thePassword, final String theEmail) {
            Validate.notNull(theUsername);
            Validate.notNull(thePassword);
            Validate.notNull(theEmail);
    
            this.username = theUsername;
            this.password = thePassword;
            this.email = theEmail;
        }
    
        // Getters / Setters / equal / hashCode / toString
    }
    

    and then I have the UserBuilder:

    public class UserBuilder {
        private String username;
        private String password;
        private String email;
    
        public UserBuilder withUsername(final String theUsername) {
            Validate.notNull(theUsername);
    
            this.username = theUsername;
    
            return this;
        }
    
        public UserBuilder withPassword(final String thePassword) {
            Validate.notNull(thePassword);
    
            this.password = thePassword;
    
            return this;
        }
    
        public UserBuilder withEmail(final String theEmail) {
            Validate.notNull(theEmail);
    
            this.email = theEmail;
    
            return this;
        }
    
        public User build() {
            User user = new User(this.username, this.password, this.email);
    
            return user;
        }
    }
    

    And you can use the builder like this:

    UserBuilder builder = new UserBuilder();
    
    try {
        User user = builder.withUsername("pmviva").withPassword("My Nifty Password").withEmail("pmviva@somehost.com").build();
    } catch (IllegalArgument exception) {
        // Tried to create the user with invalid arguments
    }
    

    The factory's solely purpose is th create valid instances of objects. In order not to duplicate creation and hydration code you can have your repositories to query a rowset from the database and delegate the creation of the object to a builder passing the rowset's data.

    Hope this helps

    Thanks Pablo

提交回复
热议问题