Problem description
The following two types of problems are often encountered in object-oriented system design:
1) In order to improve cohesion (Cohesion) and loose coupling (coupling), we often abstract some classes of public interfaces to form abstract base classes or interfaces. This allows us to point to the actual subclass implementation by declaring a pointer to the base class to achieve the polymorphic purpose.
There's a problem here. N-ary subclasses inherit from the abstract base class, and we have to write code like newxxx every time we want to use subclasses. Here are two questions:
->1. The client programmer must know the name of the actual subclass (when the system is complex, naming will be a very bad problem, in order to deal with possible name collisions, some naming may not be very readable and memorable, regardless of the different programmer's strange personal preferences.) )
->2. Program extensibility and maintenance is becoming more and more difficult.
2) There is also a case where the parent class does not know exactly which specific subclass to instantiate.
Suppose we are going to use Class B in Class A, B is an abstract parent class, and in a It is not known that the subclass of the B is to be instantiated, but it is known in subclass D of Class A. In a We have no way to directly use a newxxx-like statement, because there is no knowing what XXX is.
The above two questions also lead to the two most important features of the Factory model:
1) Define an interface for creating objects, encapsulating the creation of objects;
2) The work of the materialized class is deferred to the subclass.
In the first question, we often declare an interface to create objects and encapsulate the creation of objects. Factory here is similar to a factory (production object) in a real sense.
In the second question, we need to provide an interface to object creation objects and provide its implementation in subclasses (because only in subclasses can decide which one to instantiate).
UML Class Diagram
For the factory model, it can be divided into three categories:
- Simple Factory mode;
- Factory method mode;
- Abstract Factory mode.
For the three factory models above, it is progressively abstracted from top to bottom and more general. This article focuses on the first class (Simple Factory mode) and the second class (factory method mode).
The first case (corresponding to the "Simple Factory mode"):
The factory pattern shown is often used in system development, but this is not the greatest power of the factory pattern (as this can be solved by other means). The Factory mode not only provides an interface for creating objects, but most importantly delays the instantiation of subclasses (the second problem).
As shown (corresponding to the factory method pattern):
The application of this pattern is not just to encapsulate the creation of an object, but to put the object's creation into a subclass: Factory only provides an interface for object creation, and its implementation will be carried out in the Factory subclass Concretefactory.
Applicable occasions
Simple Factory mode:
- In the program, you need to create a lot of objects, resulting in the new operation of the object more and miscellaneous, the need to use simple Factory mode;
- Because the object creation process is that we do not need to care about, and we focus on the actual operation of the object, so we need to separate the creation and operation of objects, so that the later program extension and maintenance.
Factory method Mode:
The meaning of the factory method pattern is to define a factory interface that creates the product objects, deferring the actual creation to subclasses. It corrects the non-observance of the open-closed principle in simple Factory mode . The Core factory class is no longer responsible for product creation, so that the core class becomes an abstract factory role and is responsible only for the interfaces that a specific factory subclass must implement, and the benefit of further abstraction is that the factory method pattern allows the system to introduce new products without modifying the specific factory roles.
- At the beginning of the design, considering that the product will be extended in the later stage, the factory method model can be used;
- If the product structure is more complex, the factory method model can be used.
Since the use of design patterns is a detailed design, it is necessary to make a decision, so there is a need to weigh a number of factors, rather than using design patterns in order to use design patterns.
Code implementation
Simple Factory mode:
#include <iostream> #include <string>using namespace std;//base class Operation{public:double Numbera, Numberb;virtual Double GetResult () {return 0;}};/ /addition class Addoperation:p ublic operation{double getresult () {return numbera + numberb;}};/ /Subtraction Class suboperation:p ublic operation{double getresult () {return numbera-numberb;}};/ /multiplication Class muloperation:p ublic operation{double getresult () {return numbera*numberb;}};/ /Division class Divoperation:p ublic operation{double getresult () {return numbera/numberb;}};/ /Factory class Operfactory{public:static Operation *createoperation (char c) {
In C # You can use reflection to cancel the use of the switch, then what is used in C + +? RTTI? Switch (c) {case ' + ': return new Addoperation;break;case '-': return new suboperation;break;case ' * ': return new Muloperation;break;case '/': Return to New Divoperation;break;}}; int main () {Operation *oper = operfactory::createoperation (' + '); Oper->numbera = 9;oper->numberb = 99;cout << Oper->getresult () << Endl;return 0;}
Operation Result:
Factory method Mode:
#include <iostream> #include <string>using namespace Std;class operation{public:double Numbera, Numberb; Virtual Double GetResult () {return 0;}}; Class Addoperation:p ublic operation{double getresult () {return numbera + Numberb;}}; Class Suboperation:p ublic operation{double getresult () {return numbera-numberb;}}; Class Muloperation:p ublic operation{double getresult () {return numbera*numberb;}}; Class Divoperation:p ublic operation{double getresult () {return numbera/numberb;}}; Class Ifactory{public:virtual Operation *createoperation () = 0;}; Class Addfactory:p ublic ifactory{public:static Operation *createoperation () {return new addoperation ();}; Class Subfactory:p ublic ifactory{public:static Operation *createoperation () {return new suboperation ();}; Class Mulfactory:p ublic ifactory{public:static Operation *createoperation () {return new muloperation ();}; Class Divfactory:p ublic ifactory{public:static Operation *createoperation () {return new divoperation ();}; int main () {operation *Oper = Mulfactory::createoperation (); Oper->numbera = 9;oper->numberb = 99;cout << oper->getresult () < < Endl;return 0;}
Operation Result:
---------------------------------------------------------
#include <iostream> #include <string>using namespace std;//instance base class, Equivalent to product (for convenience, no abstraction) class leifeng{public:virtual void Sweep () {cout << "Lei Feng sweeping" << Endl;} void Wash () {cout << "Lei Feng wash clothes" << endl;}};/ /Learn Lei Feng's college students, equivalent to Concreteproductclass Student:p ublic leifeng{public:virtual void Sweep () {cout << "college students sweeping" << endl;}};/ /Learn Lei Feng's volunteers, equivalent to Concreteproductclass volunteer:p ublic leifeng{public:virtual void Sweep () {cout << "Zhiyaunzhe" < < endl;}};/ /factory base class Creatorclass leifengfactory{public:virtual Leifeng *createleifeng () {return new Leifeng ();}};/ /Factory Specific class Studentfactory:p ublic leifengfactory{public:virtual Leifeng *createleifeng () {return new Student ();}; Class Volfactory:p ublic leifengfactory{public:virtual Leifeng *createleifeng () {return new volunteer ();}; int main () {leifengfactory *sf = new Leifengfactory (); Leifeng *s = Sf->createleifeng () s->sweep ();d elete s;delete Sf;return 0;}
Operation Result:
Reference documents:
"Big talk design mode C + +"
"C + + design mode"
Also refer to the blog (its series is well written): C + + design mode-Simple Factory mode
Factory mode of design mode (c + +)