TransWikia.com

SimpleFactory vs Factory Method

Software Engineering Asked by Asier Naiz on December 10, 2021

Let’s assume a SimpleFactory that creates a group of objects:

public SimpleFactory {
   public Bycicle createBycicle(String type) {
     if(type.equals("ONE")) return new OneWheelBycicle();
     if(type.equals("TWO")) return new TwoWheelBycicle();
     if(type.equals("THREE")) return new ThreeWheelBycicle();
   }
}

This has the advantage of centralizing the creation of Bycicles in one method/class. If new Bycicles are added, there’s only one place to change the code. So far so good.

What I don’t understand is the benefits of the Factory Method. As far as I’m concerned I would always use the SimpleFactory. Does the factory method exist because a doSomething method includes code that manipulates the created object ? Because the object creation includes object manipulation ? Or may be because I can add n ConcreteFactories to group objects by factory, which I could also do in SimpleFactory adding a new parameter for the group.

Factory Method UML class diagram

2 Answers

Factories let you do two things:

  1. Select the type of the created object.
  2. Create the object.

A SimpleFactory lets you create objects of different type depending on runtime arguments. Here, both 1. and 2. happen at the same place, namely the Bicycle createBicycle(String type) method:

class Foo {
    void bar(String bicycleTypeName) {
        // The next line creates the object.
        // The type selection is made when passing the type string to the
        // factory. It is easy to create a different object by passing a
        // different string.
        Bicycle b = SimpleFactory.createBicycle(bicycleTypeName);
        [...] // use b
    }
}

The Factory (or AbstractFactory) pattern separates 2. the object creation from 1. the type selection. When creating the factory, the type of the created object is selected via type of the factory. Then you can pass this factory to other places, which can then create objects.

class Foo {
    void bar(Factory bicycleFactory) {
        // The next line creates the object.
        // The creator of the bicycleFactory has already selected the
        // object type. It is hard to create a different object type,
        // because this requires a different factory.
        Bicycle b = bicycleFactory.createBicycle();
        [...] // use b
    }
}

Often, you can use both patterns interchangeably. Usually, the SimpleFactory is easier to use and implement. However, such a factory must know all involved derived types beforehand, which is not always possible.

The SimpleFactory violates the open-closed principle (software entities (e.g., classes), should be open for extension, but closed for modification):

  • The class is not closed, because adding a new bicycle type requires changing the implementation of the Bicycle createBicycle(String typeName) method.
  • You can say that the class is closed if you forbid adding new types, but then the class is not open.

This can be a problem if you write code that is used by other people. Say you implement a library that (for some reason) needs a bicycle factory. If you go with the SimpleFactory pattern, users of the library are not able to add new bicycle types. They can not change the createBicycle method of SimpleFactory, because it is part of the library. However, if you go with the AbstractFactory pattern, users of the library can derive from it and pass their custom factories to the library, which creates their custom bicycles.

Answered by pschill on December 10, 2021

According to GoF, the factory method:

  • defines an interface for creating and object, but let the subclasses decided which class to instantiate.

  • involves a Creator class that has a FactoryMethod() which creates a Product, and ConcreteCreator which may be specializations of the Creator that override its template method and return ConcreteProducts. This means that the factory method can be embedded in any class where it could make sense, and not necessarily in distinct own class.

Your SimpleFactory implements in fact the GoF factory method pattern, with the following configuration:

  • instead of calling it FactoryMethod() you call it createBycicle() (naming detail, doesn't change anything for the pattern)
  • the SimpleFactory is the Creator (naming detail, doesn't change anything for the pattern)
  • the SimpleFactory provides a default implementation for the factory method (the other common variant is to have an abstract method, that needs to be defined in a concrete creator class).
  • the factory method is parmatrized and may return multiple kind of products (the other common variant is to have only one kind of product produced by the factory method)

So the difference is that the factory method is the more general design pattern and the simple factory is a specialization thereof, based on couple of choices you've made among those proposed in GoF (page 110-111).

Some additional remarks:

  • your default implementation creates in the factory a coupling with concrete products. This limits the extensibility of your design. You should consider raising an exception if the parameter is not among the authorized values: this would allow to extend your factory in compliance with LSP (allowing more values in the derived factories is weakening the preconditions, which is ok.
  • a terminological remark: a bicycle has by definition always exactly "two wheels" ("bi" = two). A cycle with one wheel is therefore not called "one wheel bicycle" but unicycle. And a cycle with three wheels is a tricycle. So I'd recommend renaming the classes accordingly, even if it doesn't change anything to your design ;-)

Answered by Christophe on December 10, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP