design-patterns/creational/factory_method/README.md
2020-09-29 22:05:56 +02:00

3.1 KiB
Raw Blame History

Factory Method

Summary

Factory Method is a creational design pattern that provides an interface for creating objects in a superclass, but allows subclasses to alter the type of objects that will be created.

Problem

Imagine that youre creating a logistics management application. The first version of your app can only handle transportation by trucks, so the bulk of your code lives inside the Truck class.

After a while, your app becomes pretty popular. Each day you receive dozens of requests from sea transportation companies to incorporate sea logistics into the app.

Great news, right? But how about the code? At present, most of your code is coupled to the Truck class. Adding Ships into the app would require making changes to the entire codebase. Moreover, if later you decide to add another type of transportation to the app, you will probably need to make all of these changes again.

As a result, you will end up with pretty nasty code, riddled with conditionals that switch the apps behavior depending on the class of transportation objects.

Solution

The Factory Method pattern suggests that you replace direct object construction calls with calls to a special factory method. Objects returned by a factory method are often referred to as products.

How To Implement

  1. Make all products follow the same interface. This interface should declare methods that make sense in every product.

  2. Add an empty factory method inside the creator class. The return type of the method should match the common product interface.

  3. In the creators code find all references to product constructors. One by one, replace them with calls to the factory method, while extracting the product creation code into the factory method. You might need to add a temporary parameter to the factory method to control the type of returned product. At this point, the code of the factory method may look pretty ugly. It may have a large switch operator that picks which product class to instantiate. But dont worry, well fix it soon enough.

  4. Now, create a set of creator subclasses for each type of product listed in the factory method. Override the factory method in the subclasses and extract the appropriate bits of construction code from the base method.

  5. If there are too many product types and it doesnt make sense to create subclasses for all of them, you can reuse the control parameter from the base class in subclasses. For instance, imagine that you have the following hierarchy of classes: the base Mail class with a couple of subclasses: AirMail and GroundMail; the Transport classes are Plane, Truck and Train. While the AirMail class only uses Plane objects, GroundMail may work with both Truck and Train objects. You can create a new subclass (say TrainMail) to handle both cases, but theres another option. The client code can pass an argument to the factory method of the GroundMail class to control which product it wants to receive.

  6. If, after all of the extractions, the base factory method has become empty, you can make it abstract. If theres something left, you can make it a default behavior of the method.