World without factory pattern
All the object creation logic creeps in the Client Code and it is usually in the form of IF-ELSE or SWITCH statement that return the Family of Objects based on some input.
Adding new classes make us modify the switch statement.
This switch statement may become monolithic when number of classes grow.
Client code should programmed against the relatively stable interfaces, those prevent client code to
be break in case of change and also this these interfaces can be mocked to unit test our code.
This object creation logic should be segregated and put in the separate class.
Factory Pattern
This pattern is used when we have CASE or SWITCH statement creating the family of objects. Adding new objects means updating the switch statements. This hampers the Hot Deployment. That means we simply add compiled classes to the running application to augment its functionality. This does not require us to change the already coded classes. this is the very soul of Open/Close Software Design Principle. Software should be build and feel that is made of Lego Blocks. Everything seems loosely coupled but still attached. Everything seems modular but still integrated.
Simple Factory Variation
This pattern variation is used when we have Single Family of objects, and all family of classes extend an Interface. Along with this we have one Factory Class that returns the instance of concrete class based on configurations.
Client Code ==>> (Interface + ClassA, Class B, Class C + Concrete FactoryClass)
Factory Method Variation
This pattern variation is the same case as above, but the client code does not depend upon the concrete Factory class, but we introduce the interface for the Factory classes as well. For Single Family of objects, this seems overhead. For most Single Family of objects the Simple Factory will work fine. It makes sense when we have following situation in the context of testing.
Basic theme is that client code should depend upon Interface rather than the Concrete Class.
There is One-To-One relationship between Factory and Product Class it can create. Each factory is responsible to create only One type of object.
Client Code ==>> (Interface + ClassA, Class B, Class C + Concrete FactoryClass)
Client Code ==>> (Interface + MockClassA, MockClassB, MockClassC + TestFactoryClass)
In this situation the Interface for factory cannot be avoided.
Abstract Factory Variation
This pattern variation is used when we have Multiple Families of objects. We have
1. Interface for the Factory Classes
2. Interface that all Product Classes will implement.
3. Factory Interface will have Multiple Create methods for different type of Products it can create.
There is One-To-Many relationship between Factory and Product Class it can create. Each factory is responsible to create Many type of objects.