Factory Pattern. When to use factory methods?

ID : 10051

viewed : 45

Tags : design-patternsfactoryfactory-patternfactory-method

Top 5 Answer for Factory Pattern. When to use factory methods?

vote vote

100

I like thinking about design pattens in terms of my classes being 'people,' and the patterns are the ways that the people talk to each other.

So, to me the factory pattern is like a hiring agency. You've got someone that will need a variable number of workers. This person may know some info they need in the people they hire, but that's it.

So, when they need a new employee, they call the hiring agency and tell them what they need. Now, to actually hire someone, you need to know a lot of stuff - benefits, eligibility verification, etc. But the person hiring doesn't need to know any of this - the hiring agency handles all of that.

In the same way, using a Factory allows the consumer to create new objects without having to know the details of how they're created, or what their dependencies are - they only have to give the information they actually want.

public interface IThingFactory {     Thing GetThing(string theString); }  public class ThingFactory : IThingFactory {     public Thing GetThing(string theString)     {         return new Thing(theString, firstDependency, secondDependency);     } } 

So, now the consumer of the ThingFactory can get a Thing, without having to know about the dependencies of the Thing, except for the string data that comes from the consumer.

vote vote

86

Factory methods should be considered as an alternative to constructors - mostly when constructors aren't expressive enough, ie.

class Foo{   public Foo(bool withBar); } 

is not as expressive as:

class Foo{   public static Foo withBar();   public static Foo withoutBar(); } 

Factory classes are useful when you need a complicated process for constructing the object, when the construction need a dependency that you do not want for the actual class, when you need to construct different objects etc.

vote vote

70

One situation where I personally find separate Factory classes to make sense is when the final object you are trying to create relies on several other objects. E.g, in PHP: Suppose you have a House object, which in turn has a Kitchen and a LivingRoom object, and the LivingRoom object has a TV object inside as well.

The simplest method to achieve this is having each object create their children on their construct method, but if the properties are relatively nested, when your House fails creating you will probably spend some time trying to isolate exactly what is failing.

The alternative is to do the following (dependency injection, if you like the fancy term):

$TVObj = new TV($param1, $param2, $param3); $LivingroomObj = new LivingRoom($TVObj, $param1, $param2); $KitchenroomObj = new Kitchen($param1, $param2); $HouseObj = new House($LivingroomObj, $KitchenroomObj); 

Here if the process of creating a House fails there is only one place to look, but having to use this chunk every time one wants a new House is far from convenient. Enter the Factories:

class HouseFactory {     public function create() {         $TVObj = new TV($param1, $param2, $param3);         $LivingroomObj = new LivingRoom($TVObj, $param1, $param2);         $KitchenroomObj = new Kitchen($param1, $param2);         $HouseObj = new House($LivingroomObj, $KitchenroomObj);          return $HouseObj;     } }  $houseFactory = new HouseFactory(); $HouseObj = $houseFactory->create(); 

Thanks to the factory here the process of creating a House is abstracted (in that you don't need to create and set up every single dependency when you just want to create a House) and at the same time centralized which makes it easier to maintain. There are other reasons why using separate Factories can be beneficial (e.g. testability) but I find this specific use case to illustrate best how Factory classes can be useful.

vote vote

61

It is important to clearly differentiate the idea behind using factory or factory method. Both are meant to address mutually exclusive different kind of object creation problems.

Let's be specific about "factory method":

First thing is that, when you are developing library or APIs which in turn will be used for further application development, then factory method is one of the best selections for creation pattern. Reason behind; We know that when to create an object of required functionality(s) but type of object will remain undecided or it will be decided ob dynamic parameters being passed.

Now the point is, approximately same can be achieved by using factory pattern itself but one huge drawback will introduce into the system if factory pattern will be used for above highlighted problem, it is that your logic of crating different objects(sub classes objects) will be specific to some business condition so in future when you need to extend your library's functionality for other platforms(In more technically, you need to add more sub classes of basic interface or abstract class so factory will return those objects also in addition to existing one based on some dynamic parameters) then every time you need to change(extend) the logic of factory class which will be costly operation and not good from design perspective. On the other side, if "factory method" pattern will be used to perform the same thing then you just need to create additional functionality(sub classes) and get it registered dynamically by injection which doesn't require changes in your base code.

interface Deliverable  {     /*********/ }  abstract class DefaultProducer  {      public void taskToBeDone()      {            Deliverable deliverable = factoryMethodPattern();     }     protected abstract Deliverable factoryMethodPattern(); }  class SpecificDeliverable implements Deliverable  {  /***SPECIFIC TASK CAN BE WRITTEN HERE***/ }  class SpecificProducer extends DefaultProducer  {     protected Deliverable factoryMethodPattern()      {         return new SpecificDeliverable();     } }  public class MasterApplicationProgram  {     public static void main(String arg[])      {         DefaultProducer defaultProducer = new SpecificProducer();         defaultProducer.taskToBeDone();     } } 
vote vote

50

They're also useful when you need several "constructors" with the same parameter type but with different behavior.

Top 3 video Explaining Factory Pattern. When to use factory methods?

Related QUESTION?