Factory method. What if concrete products needs different information to initialize?

Wilmi Rosa 2 роки тому оновлено Alexander 2 роки тому 1
Hello, after reading the Factory Method pattern, the following question regarding the creation of the Products arisen: what if each product needs different information at time of inicialization? Where should you put that code? Let me explain it better with the examples shown in the web: Assume that the truck class needs to be initialized with the number of wheels ( new Truck(int numberOfWheels)) , and the ship needs to be initialized with the max speed that is capable to reach, and the material of the hull.

I feel over-covered by the numerous types of solutions that can be applied to pass this information: for example, pass it on the creator itself (but not on the "createProduct" method, because each product have different types of arguments and will break the abstraction. Passing this info on the constructor of the creator itself isn't a solution either, because the creator will only be able to create a certain too much concrete type of Product)

Another solution can be to create a class for the most typical products, for example, create a "LargeTruck = Truck(wheels = 10), and continue scalling the pattern (CreatorOfLargeTrucks) but imho this is somewhat overkill, especially if this value can be freely decided by the client itself. (Introducing a random value on a website, for example).

Yet another sol should be to cast the product to its concrete type, after creation, and then set its concrete parameters, but this breaks the whole point of the pattern, right?

In any case I think that the factory pattern is a good solution to encapsulate this types of creational problems, I just don't know how to proceed in the case mentioned before. Any advice, help, experience about it? 

Thank you very much!


Hi Rosa!

Let me start by complimenting you on the good question! Not only that, your question contains a perfect answer by itself!

Creating subclasses that include some sort of customization is indeed one of the ways to solve this problem. Other commonly used options are:

1. Provide a way to pass a generic configuration object into the creation method. Very easy in dynamically typed languages, but also doable in static languages.

2. Creation method can fetch configuration from some centralized place.

3. Remember that it's all just code; you can change all of this to suit your needs, there's no "pattern dogma". If none of the above fits nicely into your code, you can simply evolve your Factory Method into something else, such as the Builder or Dependency Injection patterns: you pass an already built product into the creation method. In this case, the Creator's mission may be to cast the passed object into the desired type (because you can't narrow down the parameter type in a subclass, but you can narrow down the resulting type, according to LSP).