1. Conceptual policy patterns define a series of algorithms, encapsulate each algorithm, and enable them to replace each other. The rule mode allows algorithms to change independently of customers who use it.
Ii. Composition of policy Modes
1) Abstract policy role: a policy class, usually implemented by an interface or abstract class.
2) specific policy roles: encapsulate related algorithms and behaviors.
3) Environment role: Hold a reference to the policy class and call it to the client.
3. Supplement C ++ knowledge
The construction order of class objects is as follows:
1. allocate memory. when calling the constructor, the data members are initialized implicitly/displayed.
2. After Entering the constructor, execute general calculations in the constructor.
1) Any member variables in the class cannot be initialized during definition.
2) General data members can be initialized in the constructor.
3) The const data member must be initialized in the const initialization list.
4) Static should be initialized outside the class definition.
5) array members cannot be initialized in the initialization list.
6) You cannot specify an Explicit initialization for the array.
These six items indicate a problem: the constant array cannot be defined in C ++! Because of the conflict between 3 and 5. Can't this happen? No way, I had to turn to static data members.
At this point, my problem is solved. But I also want to take the opportunity to review C ++ class initialization:
1. Initialization list: csomeclass (): x (0), y (1 ){}
2. Out-of-class initialization: int csomeclass: myvar = 3;
3. the const constant definition must be initialized, and the initialization list should be used in the C ++ class;
4. The C ++ class cannot define a constant array.
In the C ++ class, you must do the following:
1. You must use the initialization list to initialize any const, reference type members, and any member of the class type without the default constructor.
2.Class Members cannot be initialized during definition..
3. the initialization sequence of the class members is irrelevant to the sequence of the member variables after they are selected in the constructor. The sequence of the member variables defined in the class is related.
The default inheritance mode of C ++ is private.
The object generated by C ++ new is a pointer, so the object before new must be declared as a pointer type.
Iv. Instances
Simple implementation of calculator simple factory Mode
# Include <iostream> using namespace STD; Class coperation // base class {public: int m_nfirst; int m_nsecond; virtual double getresult () {double dresult = 0; return dresult ;}}; class addoperation: Public coperation // addition {public: Virtual double getresult () {return m_nfirst + m_nsecond ;}}; class suboperation: public coperation // subtraction {public: Virtual double getresult () {return m_nFirst-m_nSecond ;}}; class ccalculatorfactory // factory class {Pu BLIC: // static method belongs to the class and does not belong to the static coperation * Create (char coperator) ;}; coperation * ccalculatorfactory: Create (char coperator) // The Implementation of the factory class {coperation * handle; // in C #, reflection can be used to cancel the switch used for judgment. What is used in C ++? Rtti ?? Switch (coperator) {Case '+': condition = new addoperation (); break; Case '-': condition = new suboperation (); break; default: condition = new addoperation (); break;} return condition;} int main () {int A, B; CIN> A> B;/* The static method belongs to the class, it can be used through objects or through classes. But it is generally recommended to use the class name, because as long as the static method defines the class, you do not need to create an instance of the class to use */coperation * op = ccalculatorfactory: Create ('-'); // static method call method op-> m_nfirst = A; OP-> m_nsecond = B; cout <op-> getresult () <Endl; return 0 ;}
The code after the simple factory mode is optimized to the policy mode is as follows:
# Include <iostream> using namespace STD; // policy base class coperation {public: int m_nfirst; int m_nsecond; virtual double getresult () {double dresult = 0; return dresult ;}}; // policy-specific class-addition class addoperation: Public coperation {public: addoperation (int A, int B) {m_nfirst = A; m_nsecond = B ;} virtual double getresult () {return m_nfirst + m_nsecond ;}}; class context // policy class {PRIVATE: coperation * op; public: Context (coperation * temp) // The parameter is the policy base class (initialized as a subclass when passed) {op = temp;} double getresult () {return op-> getresult ();}}; // client int main () {int A, B; char C; CIN> A> B; cout <"Enter the operator:"; CIN> C; switch (c) {Case '+': Context * context = new context (New addoperation (A, B); cout <context-> getresult () <Endl; break; default: break;} return 0 ;}
Here, the Policy (operator) is encapsulated into a context class, and the operation result under the corresponding sub-object is returned by passing the operator sub-object.
Cainiao implements factory and Policy Modes
The client only needs to access the context class and does not need to know any other class information. This achieves low coupling. On the basis of the above example, modify the following content
# Include <iostream> using namespace STD; // policy base class coperation {public: int m_nfirst; int m_nsecond; virtual double getresult () {double dresult = 0; return dresult ;}}; // policy-specific class-addition class addoperation: Public coperation {public: addoperation (int A, int B) {m_nfirst = A; m_nsecond = B ;} addoperation () {m_nfirst = 0; m_nsecond = 0;} virtual double getresult () {return m_nfirst + m_nsecond ;}}; class context {PRIVATE: coperation * op; public: context (char ctype) {Switch (ctype) {Case '+': op = new addoperation (3,8); break; default: op = new addoperation (); break ;}} double getresult () {return op-> getresult () ;}}; // client int main () {context * test = new context ('+ '); cout <Test-> getresult () <Endl; return 0 ;}
5. Example of mall promotion
Here, the abstract keyword is defined by Microsoft for C # And the abstract class keyword. C ++ does not have an abstract class. If you want to become an abstract class, you can define pure virtual functions in the class. As long as the class with pure virtual functions is an abstract class, the abstract class contains undefined pure virtual functions, so the object of the abstract class cannot be defined.
Simple factory implementation for mall promotions:
# Include <iostream> using namespace STD; Class cashsuper // cash charge abstract class {public: Virtual double acceptcash (double money) // cannot be set to pure virtual function, we need to generate objects later !!!! (Cannot be defined only, but not implemented) {}}; class cashnormal: Public cashsuper // fee subclass, normal charge {public: Double acceptcash (double money) {return money ;}; class cashrebate: Public cashsuper // discount fee subclass {PRIVATE: Double moneyrebate; // public: cashrebate (double moneyrebate) cannot be initialized) {This-> moneyrebate = moneyrebate;} double acceptcash (double money) {return money * moneyrebate ;}}; class cashreturn: public cashsuper // rebate billing subclass (default: private inheritance) {P Rivate: Double moneycondition; // the quota of the double moneyreturn; // The number of public: cashreturn (double moneycondition, double moneyreturn) {This-> moneycondition = moneycondition; this-> moneyreturn = moneyreturn;} double acceptcash (double money) {double result = money; If (money> = moneycondition) Result = money-(money/moneycondition) * moneyreturn; return result ;}}; class cashfactory {public: static cashsuper * Cr Eatcashaccept (string type) // generate the corresponding billing subclass {cashsuper * cs according to the subclass type; If (type = "cashnormal") Cs = new cashnormal (); else if (type = "cashrebate") Cs = new cashrebate (0.8); else if (type = "cashreturn") Cs = new cashreturn (300,100 ); return CS ;}}; int main (INT argc, char ** argv) {cashsuper * csuper = cashfactory: creatcashaccept ("cashrebate "); double result = csuper-> acceptcash (500); // 500 off, 400 cout output <"cashre Bate 500 is: "<result <Endl; return 0;} policy mode: defines the algorithm family and encapsulates them separately so that they can be replaced with each other, algorithm changes do not affect customers who use algorithms.
The major upgrade is to encapsulate the algorithm into the context, and then generate the corresponding subclass object by passing the object, and then get the result.
# Include <iostream> using namespace STD; Class cashsuper // cash charge abstract class {public: Virtual double acceptcash (double money) // cannot be set to pure virtual function, we need to generate objects later !!!! {}}; Class cashnormal: Public cashsuper // billing subclass. Normal charges are {public: Double acceptcash (double money) {return money ;}}; class cashrebate: public cashsuper // discount billing subclass {PRIVATE: Double moneyrebate; // initialization of public: cashrebate (double moneyrebate) {This-> moneyrebate = moneyrebate;} double acceptcash (double money) {return money * moneyrebate; }}; class cashreturn: Public cashsuper // the class of the rebate billing class (the default class is private inheritance) {PRIVATE: Double moneycondition; // double moneyreturn; // how much public is returned: cashreturn (double moneycondition, double moneyreturn) {This-> moneycondition = moneycondition; this-> moneyreturn = moneyreturn;} double acceptcash (double money) {double result = money; If (money> = moneycondition) Result = money-(money/moneycondition) * moneyreturn; return result ;}};/* class cashfactory {public: static cashsuper * creatcashaccept (string type) // generate the corresponding billing subclass {cashsuper * cs according to the subclass type; If (type = "cashnormal") Cs = new cashnormal (); else if (type = "cashrebate") Cs = new cashrebate (0.8); else if (type = "cashreturn") Cs = new cashreturn (300,100 ); return CS ;}}; */class cashcontext {PRIVATE: cashsuper Cs; public: cashcontext (cashsuper csuper) {This-> cs = csuper;} double getresult (double money) {return CS. acceptcash (money) ;}}; int main (INT argc, char ** argv) {// cashsuper * csuper = cashfactory: creatcashaccept ("cashrebate "); // double result = csuper-> acceptcash (500); // 500 off, 400 cashcontext * cs should be output; string type = "cashrebate "; if (type = "cashnormal") Cs = cashcontext (New cashnormal (); else if (type = "cashrebate") Cs = cashcontext (New cashrebate (0.8 )); else if (type = "cashreturn") Cs = cashcontext (New cashreturn (300,100); cout <"cashrebate 500 is" <CS-> getresult (500) <Endl; return 0 ;}
This still has a disadvantage: Let the client determine which subclass to generate.
The improvement strategy is to integrate the policy model with the factory model.
# Include <iostream> using namespace STD; Class cashsuper // cash charge abstract class {public: Virtual double acceptcash (double money) // cannot be set to pure virtual function, we need to generate objects later !!!! {}}; Class cashnormal: Public cashsuper // billing subclass. Normal charges are {public: Double acceptcash (double money) {return money ;}}; class cashrebate: public cashsuper // discount billing subclass {PRIVATE: Double moneyrebate; // initialization of public: cashrebate (double moneyrebate) {This-> moneyrebate = moneyrebate;} double acceptcash (double money) {return money * moneyrebate; }}; class cashreturn: Public cashsuper // the class of the rebate billing class (the default class is private inheritance) {PRIVATE: Double moneycondition; // double moneyreturn; // how much public is returned: cashreturn (double moneycondition, double moneyreturn) {This-> moneycondition = moneycondition; this-> moneyreturn = moneyreturn;} double acceptcash (double money) {double result = money; If (money> = moneycondition) Result = money-(money/moneycondition) * moneyreturn; return result ;}};/* class cashfactory {public: static cashsuper * creatcashaccept (string type) // generate the corresponding billing subclass {cashsuper * cs according to the subclass type; If (type = "cashnormal") Cs = new cashnormal (); else if (type = "cashrebate") Cs = new cashrebate (0.8); else if (type = "cashreturn") Cs = new cashreturn (300,100 ); return CS ;}}; */class cashcontext {PRIVATE: cashsuper Cs; public: cashcontext (string type) {If (type = "cashnormal ") this-> cs = new cashnormal (); else if (type = "cashrebate") This-> cs = new cashrebate (0.8 ); else if (type = "cashreturn") This-> cs = new cashreturn (300,100);} double getresult (double money) {return CS. acceptcash (money) ;}}; int main (INT argc, char ** argv) {cashcontext * cs = new cashcontext ("cashrebate "); cout <"cashrebate 500 is" <CS-> getresult (500) <Endl; return 0 ;}
In this way, the client only needs to change the amount and discount methods. The upgrade from a simple factory is as follows: a simple factory requires customers to call two classes: supercash and cashfactory. After integration, you only need to call cashcontext.
Compared with the policy mode, the client has less judgment and is more concise.