views:

210

answers:

2

In the book Domain Driven Design, by Eric Evans, in Chapter 6 in the section on "Factories" (page 139) it says the following:

"The two basic requirements for any good FACTORY are:

...

"2. The FACTORY should be abstracted to the type desired rather than the concrete class(es) created."

Could you please elaborate on what is meant by that statement about basic requirement number 2.

+6  A: 

I think it means you should never return a concrete type from your factory. For example, if you have an interface, let's say ISomething, an anstract class SomethingBase and finally some classes that implement this interface and inherit from the base class. Your creation method should return the interface type, intead of the base type. I think that is the idea.

public ISomething Create() { ... }

Instead of

public SomethingBase Create() { ... }

I hope it helps, Carlos.

Carlos Loth
thanks for your quick reply. Although i am still a bit bit confused cos it also says later in the book (on bottom of p.143) "The FACTORY is coupled to the concrete class of the products;" Luckily I am developing in php so ''return types'' are not too much of an issue technically (although conceptually still important )
JW
I think it says it because in most of cases you will instantiate the concrete class inside the Create method using the new operator. Thus, you will have a strong coupling between the creational method and the concrete type. Your consumers won't necessarily reference the concrete type, only the interface. However the factory class will need to reference the concrete type.
Carlos Loth
I think i see. So, basically make use of the various creational patterns (GoF) to keep the signature and return types of the factory classes as generic as possible to shield the concrete-specific implementations. But you can still have a factory class that is tied to a concrete domain object so long as its interface is generic. So, LampshadeFactory and a SofaFactory are still ok as long as they keep hidden behind FurnitureFactory's abstract interface.
JW
+1 but see my anser for additional guidance.
Mark Seemann
+1. That's what I'd interpret it to mean.
RichardOD
+1  A: 

Carlos Loth's answer is correct, but you should always remember to use an Abstract Factory as well, as this will allow you to couple concrete factories to concrete types without coupling consumers to concrete factories or types.

public interface ISomethingFactory
{
    ISomething Create();
}

public class SomethingFactory : ISomethingFactory
{
    public ISomething Create()
    {
        return new Something();
    }
}
Mark Seemann