design-patternsoopdomain-driven-designfactorydomain-object

How do you use Interfaces with the Factory Pattern in Domain-Driven Design?


Does it make sense to use interfaces for your domain object factories by default, or should interfaces be reserved for the factory classes only when you need them?

public IUserFactory
{
    User CreateNewUser();
}

public UserFactory : IUserFactory
{
    public User CreateNewUser()
    {
        return new User();
    }
}

Solution

  • Here's a translation of the same problem into Java.

    Original example

    public interface UserFactoryIF
    {
       User createNewUser();
    }
    

    Then the implementation of the Factory

    public class UserFactory implements UserFactoryIF
    {
         public User createNewUser()
         {
             // whatever special logic it takes to make a User
             // below is simplification
             return new User();
         }
    }
    

    I don't see any special benefit to defining an interface for the factory, since you're defining a single interface for a centralized producer. Typically I find that I need to produce many different implementations of the same kind of product, and my factory needs to consume many different kinds of parameters. That is, we might have:

    public interface User
    {
        public String getName();
        public long getId();
        public long getUUID();
        // more biz methods on the User
    }
    

    The factory would look like this:

    public class UserFactory {
    
        public static User createUserFrom(Person person) {
            // ...
            return new UserImpl( ... );
        }
    
        public static user createUserFrom(AmazonUser amazonUser) {
             // ... special logic for AmazonWS user
            return new UserImpl( ... );          
        }
    
        private static class UserImpl implements User {
           // encapsulated impl with validation semantics to
           // insure no one else in the production code can impl
           // this naively with side effects
        }
    }
    

    Hope this gets the point across.