Similar to the prototype, the factory method is also the design mode for creating objects.
Official definition:
"Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses ."
Define an interface for creating objects in the base class so that the subclass decides which class to instantiate. The factory method delays the instantiation of a class to the subclass. The problem to be solved by the factory method is the creation time of the object. It provides an extension policy, which is in line with the open and closed principle. The factory method is also called Virtual Constructor ). As shown in, it is the class structure diagram of the factory method:
When can I use the factory method?The factory method can be used as follows: When a class does not know the class of the object it must create, a class wants its subclass to determine the object to be created.
The official definition is always awesome. I translated this official definition in Vernacular: The Factory method is designed for instantiated objects. we can consider this example: A parent class Animal has two sub-classes [entity class]: Dog and People. The factory class AnimalFactory has two subclasses: DogFactory, PeopleFactory: AnimalFactory, which has an instantiation method:
+(Animal *)createAnimal{ return [[Animal alloc] init];}
Dog inherits from Andimal, and DogFactory (inherits from AnimalFactory) overrides this method:
+(Animal *)createAnimal{ return [[Dog alloc] init];}
People inherits from Andimal and PeopleFactory (inherits from Animal) to override this method:
+(Animal *)createAnimal{ return [[People alloc] init];}
During use, the instantiation can be postponed to the subclass: for example:
Dog * dog1 = [DogFactory createAnimal];
Factory model:
The factory mode is divided into three types based on the degree of Abstraction: simple factory mode (also called static factory mode ),Factory method modeAnd Abstract Factory mode. Factory mode is a commonly used mode in programming. Its main advantages include:
- The code structure can be clear,Effectively encapsulateChange. In programming, product class instantiation is sometimes complicated and changeable. Through the factory model, product instantiation is encapsulated, so that callers do not need to care about the product instantiation process at all, you only need to rely on the factory to get the desired product.Shield callers from specific product categories. If the factory mode is used, the caller only cares about the product interface. As for the specific implementation, the caller does not need to care about it. Even if the specific implementation is changed, there is no impact on the caller.Reducing Coupling. The instantiation of product classes is usually very complex, and it depends on a lot of classes, and these classes do not need to be known to the caller. If the factory method is used, all we need to do is instantiate the product class and hand it over to the caller. For callers, the classes on which the product depends are transparent.
Applicable scenarios:
Whether it's a simple factory model, a factory method model, or an abstract factory model, they have similar features, so their application scenarios are similar.
First, as a class creation modeComplex objectsYou can use the factory method. One thing to note is that complex objects are suitable for using the factory mode, while simple objects, especially objects that can be created through new, do not need to use the factory mode. If the factory mode is used, a factory class needs to be introduced, which will increase the complexity of the system.
Second, the factory model is a typical decoupling mode, which is particularly evident in the factory model. If the caller needs to add dependency when assembling the product, the factory mode can be used. This will greatly reduce the coupling between objects.
Thirdly, because the factory model relies on the abstract architecture, it submits the task of instantiating the product to the implementation class for better scalability. That is to say, when the system requires better scalability, we can consider the factory model. Different products are assembled with different implementation factories.
Typical applications
To illustrate the advantages of the factory model, there may be no more suitable example than assembling a car. The scenario is as follows: a car consists of an engine, a wheel, and a chassis. Now a car needs to be assembled and handed over to the caller. If the factory mode is not used, the Code is as follows:
[Java]View plaincopy
- Class Engine {
- Public void getStyle (){
- System. out. println ("this is the car's engine ");
- }
- }
- Class Underpan {
- Public void getStyle (){
- System. out. println ("this is the chassis of a car ");
- }
- }
- Class Wheel {
- Public void getStyle (){
- System. out. println ("this is a car tire ");
- }
- }
- Public class Client {
- Public static void main (String [] args ){
- Engine engine = new Engine ();
- Underpan underpan = new Underpan ();
- Wheel wheel = new Wheel ();
- ICar car = new Car (underpan, wheel, engine );
- Car. show ();
- }
- }
We can see that the caller needs to instantiate the engine, chassis, and tires in order to assemble the car. The components of these cars are irrelevant to the caller, seriously violating the Demeter Law, and the coupling is too high. And is not conducive to expansion. In addition, the engine, chassis, and tires in this example are more specific. in actual application, the components of these products may also be abstract, and the caller does not know how to assemble the product. If the factory method is used, the entire architecture is much clearer.
[Java]View plaincopy
- Interface IFactory {
- Public ICar createCar ();
- }
- Class Factory implements ifacloud {
- Public ICar createCar (){
- Engine engine = new Engine ();
- Underpan underpan = new Underpan ();
- Wheel wheel = new Wheel ();
- ICar car = new Car (underpan, wheel, engine );
- Return car;
- }
- }
- Public class Client {
- Public static void main (String [] args ){
- IFactory factory = new Factory ();
- ICar car = factory. createCar ();
- Car. show ();
- }
- }
After the factory method is used, the coupling degree of the call end is greatly reduced. In addition, the factory can be expanded. If you want to assemble other cars in the future, you only need to add a factory implementation. Both flexibility and stability have been greatly improved.
I have been pursuing "high coupling and low cohesion" when writing code. It seems that this method is helpful to me.