5

I'm currently learning about design patterns. I learned about the Factory Method pattern.

This pattern means that in order to implement a factory to create objects, one should subclass the class that needs these objects, and have the subclass create them. This way the superclass only works with more abstract references instead of the concrete implementations the subclass generates, which creates a loosely coupled design.

This usually means the superclass becomes abstract, since it's createObject() method must be abstract so that the subclass containing the factory method will have to implement this method.

Like any factory pattern, this pattern encapsulates the creation of the concrete object, and allows the client to work with a higher level of abstraction. But this specific pattern is built on inheritance.

What I don't understand is - Why would anybody go through all the trouble of subclassing the class that needs a factory and making it abstract? Composition is so much better for this purpose in any way.

It makes much more sense to create an abstract class or an interface called Factory. It would declare one method: createObject(). We create concrete implementations of it for different purposes (WeaponFactory, TitleFactory..) Then, we give the client a Factory member instance factory. This reference is set to whatever concrete Factory is needed at runtime, and the client can simply use factory's createObject() when needed (without having to know what concrete implementation factory is holding).

I don't understand why one would go through the trouble of subclassing a class and making it abstract just for the benefit of allowing it to use a factory in a loosely-coupled manner.

The simple composition-based design I described is better in any way - I think.

Do you agree? Could you explain why anybody would use the Factory Method Pattern I described?

3

The Design Patterns book is descriptive, not prescriptive; it describes the patterns the GoF have observed in the wild; patterns that solve problems.

Some problems can be solved in more than one way.

The alternative you describe is also my preferred approach, but it's also described in the book: it's a combination of the Abstract Factory and Strategy patterns. You use an Abstract Factory as a Strategy.

I don't understand why one would go through the trouble of subclassing a class and making it abstract just for the benefit of allowing it to use a factory in a loosely-coupled manner.

For the exact same reason that you would combine Abstract Factory and Strategy. However, the best solution partly depends on your language.

If, for example, you were programming in Eiffel, Factory Method would probably be easier, because Eiffel has multiple inheritance, but (IIRC) no interfaces.

Also, if you're using a language where you can create a derived value on the spot (such as Java or F#), Factory Method might actually be easier than the Abstract Factory/Strategy combo.

  • Thanks for your answer. You posted this a while ago but I got a question regarding this: I understand the factory patterns well as a whole, but I always have trouble drawing the line between Factory Method and Abstract Factory. In both patterns, there's an abstract superclass, and a number of concrete subclasses. The only difference I see between the two patterns (and I've tried for long to find another difference), is that Abstract Factory is always said to "produce a family of objects", while Factory Method usually produces one object. (Continuing in the next comment) – Aviv Cohn Apr 4 '14 at 18:54
  • The only additional difference I can think of is the fact that the abstract superclass in Factory Method, usually does some manipulation on the object it recieves from it's subclass, before returning it to the client. While the abstract superclass in Abstract Factory, usually isn't said to do this. Is this actually the difference? Can you explain the difference to me? I'm having a hard time understanding (been reading a lot on this site and the web, didn't help). Thanks – Aviv Cohn Apr 4 '14 at 18:58
  • OR: One additional option for the difference, may be this: In Factory Method, the client itself is subclassed, to get the object from it's subclass. While in Abstract Factory, the superclass-subclasses system is extenal to the client, and composed with it. Does this mean that if I create a Factory Method system (an abstract superclass and a number of subclasses), and give a reference to it to the client, instead of subclassing the client itself - it becomes an Abstract Factory instead of a Factory Method? A little confused here.. Would appreciate your help :) – Aviv Cohn Apr 4 '14 at 19:00
  • That last comment of yours is zeroing in on the differences. Factory Methods usually exist only for the benefit of the base class. It's a way to apply the Open/Closed Principle by enabling clients to extend that particular class by overriding its Factory Method(s). Abstract Factory, on the other hand, only has a single responsibility: it creates objects. If composed with client classes, it can be reused across many different classes. Note also that Abstract Factory doesn't rely on inheritance. It can implement a factory interface instead of deriving from a base class. – Mark Seemann Apr 4 '14 at 19:14
  • Please let me see if I understand the differences: Let's say there is a class that needs an object. This class is called the Client. We have two ways to achieve this: to use Factory Method or to use Abstract Factory. I'll describe both and their difference. Using Factory Method, we create a method inside Client createObject(), and subclass Client. The subclass will override createObject(). Client would call createObject() when it needs to make an object, and the subclass will give it the object that answers to some general interface, without the Client knowing the concrete type (...) – Aviv Cohn Apr 4 '14 at 19:25
0

In general i agree that composition its better than inheritance. GOF design patterns are great because there are probably the first attempt to build a language (the patterns are a language for me) in a new level of abstraction, at design level instead of programatic level, this is great, but some concrete patterns are perhaps obsolete or can be improved to adapt to your concrete situation, technology or preferences. The study of patterns is a good thing, can teach you some good OO tricks and techniques, but the application of patterns "by the book" its never a good idea IMMO.

Anyway, i see a problem with your design, at least a problem in a static typed language, WeaponFactory return weapons and titleFactory return titles i suppose, the return type for "createObject" its different and this return type is part of the signature of the method. But off course with composition and DI you can achieve the same goals that the factory method try to achieve. For example:

Client clientWithRealWeapon = new Client(new RealWeaponsFactory());
Client clientWithMocksWeapon = new Client(new MockWeaponsFactory());

its a solution with composition and DI, the same can be done creating two subclass of client: ClientWithRealWeapons and ClientWithMocksWeapons that override a method for creating weapons.

0

I think that you're looking at the problem the wrong way. If you have a need to create one of several subclasses, then you'll need to use the Factory method as you've described it to solve the problem.

For example, if you have a system where you need to have the vast majority of your code be the same but only vary in a few details, then subclassing makes sense in its own right and you'll do that, then create the factories that are able to kick out the correct subclasses based on the rules each needs. You might also have a legacy system where subclasses are already in use, and you find that as it scales you want to add factories to help with creation of your objects.

If you are using something like an Entity system and you don't need subclasses of your Product object, by all means don't create them. However, you might want to make sure your single Class at least implements an Interface, because every once in a while you need to use a completely unrelated implementation when you get a requirement you didn't see coming.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.