Motivation for Simple Factory and Factory Method Pattern
Asked Answered
T

6

11

I know there are a lot of questions out there about differences of different factory patterns, but the answers are so different and confusing. The books that i read use unclear and (over)simplified examples. I have a number of questions even after reading Wikipedia explanations, and a lot of online explanations about them including all on these site. The book that I'm currently reading is Head First Design Patterns.

In Simple Factory the client uses separate class (Creator) with factory method (which CAN be static) to return Products.

In Factory Method Pattern the Creator and the Client are the same thing and they use abstract method in the same class to create new Products, on which they operate in that same class. Of course the Creator (or Client) are abstract, so the decision about making the Concrete Product is deferred to sub-classes.

  1. Is my understanding correct (for ex. are the Client and Creator in FMP the same thing, I never see Client in FMP diagram)?

  2. In Factory Method Pattern it seams that the create method is not reusable outside of the Creator, so it can only be reused when making some new Creator?

  3. What are the situations where I can choose one over the other?

(P.S. Please don't mark this as duplicate, I want to make this thing clear on this site)

Timberland answered 30/12, 2013 at 21:45 Comment(1)
Related: Differences between Abstract Factory Pattern and Factory MethodAmyotonia
B
7

Simple Factory is a factory in the form of a class. Because of that it doesn't solve the problem with elegance, since for every new subclass of Product you will have to edit the switch statement in the create() method. This is a violation of the Open/Close Principle. A potential way to make a Simple Factory useful would be to use class registration as sawn here: http://www.oodesign.com/factory-pattern.html

Factory Method is a factory in the form of a method (hence the name). This doesn't violate the Open/Close Principle since you deal with change by extending and not by modifying code.

Your understanding is correct. Client and Creator/Factory in FMP are the same since the Factory (method) is part of the Client.

It is true that the create method in FMP is not reusable. That is ok though, because this is not an attempt to create an application-wide Factory of the Product, but a way for the Client to create his depended objects without using new.

I cannot answer you third question since I believe it is based on preference.

Booted answered 29/1, 2015 at 13:55 Comment(0)
W
5

Simple Factory:

Definition:

Creates objects without exposing the instantiation logic to the client. Refers to the newly created object through a common interface

public interface PaymentMethod {
    public void makePayment();
}

class CreditCard implements PaymentMethod {
    public void makePayment() {
        System.out.println("Payment through credit card...");
    }
}

class NetBanking implements PaymentMethod {
    public void makePayment() {
        System.out.println("Payment through net banking...");
    }
}

public class PaymentMethodFactory {
    public static PaymentMethod getPaymentMethod(String method) {
        if ("creditcard".equalsIgnoreCase(method)) {
            return new CreditCard();
        } else if ("netbanking".equalsIgnoreCase(method)) {
            return new NetBanking();
        } else {
            throw new IllegalArgumentException("Payment method not supported!");
        }
    }
}

public class SimpleFactoryTest {

    public static void main(String[] args) {
        PaymentMethodFactory factory = new PaymentMethodFactory();
        PaymentMethod paymentMethod = factory.getPaymentMethod("creditcard");
        paymentMethod.makePayment();
    }

}

Factory Method:

Definition:

Defines an interface for creating objects, but let subclasses to decide which class to instantiate Refers the newly created object through a common interface.

public interface PaymentMethod {
    public void makePayment();
}

class CreditCard implements PaymentMethod {
    public void makePayment() {
        System.out.println("Payment through credit card...");
    }
}

class NetBanking implements PaymentMethod {
    public void makePayment() {
        System.out.println("Payment through net banking...");
    }
}
public interface IPaymentMethodFactory {
    public PaymentMethod getPaymentMethod();
}

class CreditCardFactory implements IPaymentMethodFactory {
    public PaymentMethod getPaymentMethod() {
        return new CreditCard();
    }
}

class NetBankingFactory implements IPaymentMethodFactory {
    public PaymentMethod getPaymentMethod() {
        return new NetBanking();
    }
}

public class FactoryMethodTest {

    public static void main(String[] args) {
        IPaymentMethodFactory factory = new CreditCardFactory();
        PaymentMethod paymentMethod = factory.getPaymentMethod();
        paymentMethod.makePayment();
    }

}
Wei answered 22/5, 2017 at 5:50 Comment(2)
this example is so handful and concise . thank you . but can you show AbstractFactory here too?Philina
Finally, I got the differences between Simple Factory and Factory Method along with their definitions and Examples. Thanks.Khasi
G
3

Simple Factory - This isn't an official GoF pattern, infact I had no idea what you were talking about until I pulled out my Head First Design Pattern Book. Simple Factory is just a method that can return different hardcoded subtypes.

public Pizza createPizza(String type){
     if(type.equals("cheese")){
        return new CheesePizza();
     }else if (type.equals("pepperoni")){
        return new PepperoniPizza();
     }
     ...
}

The problem with this code is you are stuck with only the hardcoded types. If you want to change how the method works, or what types are returned you have to modify code and recompile. Adding new types will be very difficult.

Factory Method - you do most of the work in a super class but put off deciding what sort of object you will be working with until runtime. Often the superclass needs to create a worker object of some default type but the superclass allows subclasses to specialize the worker. Factory Methods are usually used when an AbstractFactory is overkill but one downside is it forces you to use inheritance which has its own set of maintenance and design problems. This is very similar to SimpleFactory except you use inheritance instead of a discriminator to get different return types.

public void foo(){
   Bar bar = createBar();
   //do stuff with bar

}

//method is protected so subclass can override it to return something else
protected Bar createBar(){
   return new DefaultBar();
}

AbstractFactory - Create Objects knowing only the interface they implement not the actual class. AbstractFactories make it easy for code to work in different systems because you don't need to know the concrete factory or concrete products that are used.

For example Collection.iterator() is an abstract factory of Iterator objects. Classes such as LinkedList or HashSet have their own implementations of iterator() (and therefore are Concrete Factories) that return different classes that implement the iterator interface (the concrete product)

Once you finish Head First Design Patterns I recommend Holub on Patterns the code is a little dated (pre-generics) but you really learn a lot about how multiple patterns interact with one another in non-trivial code samples. The book only has 2 code samples which each cover about 10 patterns and take 100+ pages each to explain step by step

Greensand answered 31/12, 2013 at 15:30 Comment(6)
He asked about Factory Method vs. a simple Factory. Abstract Factory is not a simple Factory. It's for creating families of objects.Inhalator
@Inhalator you're right. I didn't notice the "simple" word since that isn't really a pattern. I've updated my answer to include that too. Thanks!Greensand
Thanks a lot for the book recomendation :). About the examples I don't agree. First I don't think Simple Factory is just a method, I think it's an object with this factory method. As such I think you can provide different "factory" objects with this method to the client, so it can have different factories (HF Design Patterns page 119, you provide different factories, but the book doesn't show the whole code, how you implement them, so the example is confusing).Timberland
(In that example) maybe you subclass the Simple Factory, and provide different factories to the client object (in a constructor) - but I don't know if this is true or if then the idiom becomes then Abstract Factory? I agree that Simple Factory isn't pattern, but you haven't answered my questions.Timberland
Simple Factory is not really a pattern. It simply decouples the PizzaStore from Pizza creation code. So that PizaaStore becomes "close for modification". The simple factory itself is not close for modification though. Ant that is never its intention.Neil
Rather than subclassing in the second approach, can we make our factory an interface, and have different implementations of the factory (to create different kinds of objects) and inject the appropriate factory type?.Are they equivalent?Fizzy
A
2

You are seeing examples of two styles of factory method because there are two completely separate situations where they are appropriate.

The first type - which seems to coincide with what you are being led to call a simple factory comes about when you have a relatively complicated object that can be difficult to create because of it's complexity.

The classic example here is the Pizza class which has a PizzaConstructor class (or some similar name) where much of the clevers required to build the Pizza object is encoded into the Constructor.

There's a nice discussion here but the salient point is that this form puts the clevers of how to construct the Pizza in a Factory rather than bogging down the Pizza class.

With this technique you can make constructor code that is much clearer than it would normally be.

Pizza pizza = PizzaFactory.addTopping(Cheese)
    .addTopping(Anchovies)
    .thickCrust()
    .stuffedCrust(Gruyere)
    .stoneBaked()
    .buildPizza();

The second situation for the use of factories is when you need your class to be able to actually make objects of a supplied type. This is difficult without the user supplying a factory mechanism for you to use. The user then supplies a factory mechanism of some sort, perhaps a factory object or maybe they extend your abstract class and provide a concrete constructor method.

Aksoyn answered 31/12, 2013 at 0:4 Comment(4)
1. Well, there are situations other then having an object that's hard to create, that makes me want to use Simple Factory, or not? 2. So you want to say that we use the Factory Method when we want the user of our framework(?) to supply the concrete construction mechanism?Timberland
Please clarify (expand) your code to make it complete, for ex. with the calling code, without abbreviations.Timberland
This is more the Builder pattern than a factory.Greensand
@Greensand Any program element that is responsible for the cration of other objects is called a factory ...Quean
A
1

Here is a simple guideline I can think of following -

The basic differentiation between these two is one provides a concrete creator (Simple Factory) while the other(Factory method) supports decoupling of creator by inheritence so that multiple creators can be supported. An example to make it clearer -

  1. Factory Method - Consider creating a Button with different types - Toggle, ImageButton etc. Its more likely that you would have different creators of Button. For eg. based on different operating systems, WindowsButtonFactory, OSXButtonFactory etc. Factory method is suitable in this case with an abstract class ButtonFactory being implemented by WindowsButtonFactory, OSXButtonFactory (and many more in future).
  2. Simple Factory - Consider creating Book based on genre - Fiction, NonFiction etc. More than often you would think a concrete Factory should be enough here.
Atwekk answered 13/7, 2014 at 6:36 Comment(0)
Q
0

First of all , I don't see the "factory method pattern" as a standalone pattern (never headred of this pattern untill i've read wikipedia as you said in your question) . I see it more as a mix of factory pattern + strategy pattern .

You can imagine an object factory as a simple object creator .
When strategy pattern comes into play inside an object factory then you begin to add more logic about the creation of the object, to hide it from the client (the client should not know how the objects are created, leave this responsability to the factory).

A factory can be of many types (the decision of factory creation depends on many factors) :
- When thinking about object associations , an object may be composed by multiple objects . Here the root object may have a factory method that will create the need objects . This factory method is responsible for checking if the newly added objects keep the root in a valid state . So here the strategy pattern (factory method pattern as you call it) may come into play :

class Car {

    public $carType;
    public $audioSystem;

    public function __construct($carType) {  
        $this->carType = $carType;  
        $this->audioSystemFactory();  
    }        

    public function audioSystemFactory() {
        if ($this->carType == 'hipster') {
            $this->audioSystem = new VynilPlayer();
        }
        else {
            $this->audioSystem = new Mp3Player();
        }
    }

    public function startMusic($albumName) {
        $this->audioSystem->playSongs($albumName);
    }

}

class VynilPlayer {
    public $vynilAlbums = array('MJ TOP HITS', 'JUSTIN BIEBER TOP HITS');

    public function playSongs($albumName) {
        $this->loadVynil();
        $this->startPlayer();
    }

    public function loadVynil() {

    }

    public function startPlayer() {

    }
}

class Mp3Player {
    public $dvdAlbums = array('MJ TOP HITS', 'JUSTIN BIEBER TOP HITS');

    public function playSongs($albumName) {
        $this->loadDVD();
        $this->startPlayer();
    }

    public function loadDVD() {

    }

    public function startPlayer() {

    }
}
  • You can also have a factory class that is responsible for the creation of only one type of object . You make a factory class per object type when the creation logic is very complex .

  • Even a primitive form of instanciation like a class constructor can be viewed as an object factory .

Factories are made to hide the implementation logic of some objects . You add strategy pattern to a factory to hide these details from the client .

Quean answered 2/1, 2014 at 0:43 Comment(4)
Well, Factory Method Pattern is an official GOF pattern. In it you have a factory method inside your class Car that is abstract (or implemented with a default behavior) and you must subclass Car and implement this method in the subclasses to provide specific behavior (the factory method may take parameter too). Don't know if it is applicable in this case? I hope my understanding is correct? But I don't see real benefit in doing this (at least not over the simple factory, this is my original question, what are the benefits and diff. between them?), maybe I'm not object-oriented in my thoughts.Timberland
THe audioSystemFactory is the factory method you are talking about . But i simply don't see it as a standalone pattern . Actually there are 2 patterns involved here : factory and strategy . The logic of the "factory method" is a simple strategy that behaves differently depending on the context . I see the factory pattern as a solution to the problem that rises when the client has to know too much about the structure/behaviour of the manipulating objects . This factory method you are talking about is a simpel strategy . This is a simple behaviour that a fully fledge factory class may include .Quean
Maybe try reading this to make an ideea about the role of factories : amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/…Quean
Well you must know that factory pattern doesn't exist. The books (ex. Head First Design Patterns) call it an idiom. <BOLD>What exactly this idiom represents <BOLD>, and how it is related to Factory Method Pattern (as it's called in Design Patterns from GOF) is my big mystery? You say Factory Method Pattern is combination of this idiom and Strategy Pattern? This is possible, but I'm not convinced. (I'm familiar with Java) My other question was when to use which?Timberland

© 2022 - 2024 — McMap. All rights reserved.