- One of the most widely used creational patterns is the Factory.
- This pattern is aptly named, as it calls for the use of a specialized object solely to create other objects, much like a real-world factory.
- We need Factory pattern:
- To eliminate new keywords to create on client.
- The client is not aware of the concrete classes.
As with other design patterns, there are countless variations of the Factory pattern, although most variants typically used the same set of primary actors, a client, a factory, and a product. A client is an object that requires an instance of another object (the product) for some purpose. Rather than creating the product instance directly, the client delegates this responsibility to the factory. Once invoked, the factory creates a new instance of the product, passing it back to the client. Put simply, the client uses the factory to create an instance of the product. Figure 1 shows this logical relationship between these elements of the pattern.
Figure 1. Factory pattern logical model
The factory completely abstracts the creation and initialization of the product from the client. This indirection enables the client to focus on its discrete role in the application without concerning itself with the details of how the product is created. Thus, as the product implementation changes over time, the client remains unchanged.
While this indirection is a tangible benefit, the most important aspect of this pattern is the fact that the client is abstracted from both the type of product and the type of factory used to create the product. Presuming that the product interface is invariant, this enables the factory to create any product type it deems appropriate. Furthermore, presuming that the factory interface is invariant, the entire factory along with the associated products it creates can be replaced in a wholesale fashion. Both of these radical modifications can occur without any changes to the client.
Most implementations of the Factory pattern use two abstract classes, Factory and Product, to provide the invariant interfaces discussed in the logical model. Although we could utilize pure interfaces for this purpose, the use of abstract classes enables us to place common instance behavior in the abstract class. In addition, abstract classes offer versioning benefits over pure interfaces.