The last time, "Big talk design mode C + +-Simple factory model" pointed out the shortcomings of the simple factory model, that is, against the development-closure principle, the main reason is because of the use of switch judgment structure, so as to modify or add new objects need to change the simple factory class code, how to change the switch structure, The table-driven approach is ready to go.
The table driver method is described in the Data Driven programming table driver method.
1, interface-oriented programming, first to transform the abstract interface class IOperation
Class Ioperation{public:ioperation (): m_nnuml (0), M_NNUMR (0) {}virtual~ioperation () {}virtualvoidsetnum (int nNuml = 0, int NNUMR = 0) {m_nnuml = NNUML;M_NNUMR = NNUMR;} Virtualintcalculateresult () = 0;public:typedefioperation* (callback* fn_createobject) ();p rotected:intm_nnuml, m_ NNUMR;};
Interface basically no change, because the table-driven method needs to fill in the Table drive function interface, so first define a definition of the interface function, used to produce the specific interface object.
2. Transforming the Interface object class
Class Coperation_add:public Ioperation{public:intcalculateresult () {returnm_nnuml + m_nnumr;} Staticioperation*callback CreateObject () {Returnnewcoperation_add ();}; Class Coperation_dec:public Ioperation{public:intcalculateresult () {RETURNM_NNUML-M_NNUMR;} Staticioperation*callback CreateObject () {Returnnewcoperation_dec ();};
The CreateObject () static function is added and the function is used to produce this object. Because table-driven functions are used for callbacks, they need to be defined as static callback functions.
3, change the factory class, increase the drive table transformation switch structure (FOCUS)
Class Cclassfactory{public:cclassfactory () {}virtual ~cclassfactory () {}booladdoperationfunc (char cOperation, Ioperation::fn_createobject func) {if (func) {m_mapoperationfunc[coperation] = func;returntrue;} Returnfalse;} Ioperation*createobject (char coperation) {Ioperation::fn_createobjectfunc = M_mapoperationfunc[coperation];if (func ) {Returnfunc ();} Returnnull;} Protected:std::map<char, ioperation::fn_createobject>m_mapoperationfunc; Using map to implement the driver table};
The switch in the factory class disappears, replacing the driver function with the operator key in the map and making the call. At the same time, add the new operator and corresponding driver function interface Addoperationfunc (), so that if you need to increase the object or modify the operator corresponding to the driver function, call this interface, the flexibility greatly increased.
4. Examples of Use
Voidtest () {cclassfactoryocclassfactory;ioperation*poioperation = null;// Add object factory to the production object Occlassfactory.addoperationfunc (' + ', coperation_add::createobject); Occlassfactory.addoperationfunc (' -', coperation_dec::createobject);p oioperation = occlassfactory.createobject (' + '); if (poioperation) {poIOperation- >setnum (2, 3);p rintf ("2 + 3 =%d\n", Poioperation->calculateresult ());d elete Poioperation;} Poioperation = Occlassfactory.createobject ('-'); if (poioperation) {Poioperation->setnum (2, 3);p rintf ("2 + 3 =%d\n", Poioperation->calculateresult ());d elete Poioperation;}}
You need to add operators and corresponding driver functions before use, so that the user's task is increased, and the class needs to be recognized by the user increases, the encapsulation is reduced. Can it be further improved?
5, further improve the simple factory class, improve packaging
Class Cnewclassfactory:cclassfactory{public:virtual~cnewclassfactory () {}virtualvoidinit () {AddOperationFunc (' + '), Coperation_add::createobject); Addoperationfunc ('-', Coperation_dec::createobject);}};
New Simple factory class, added an initialization function init (), in place of the user's operator and corresponding driver function, so that the user only need to call the init () function, packaging further improve, then some students may ask, if you want to add new objects, you must not change the init () function code , this does not run a lap and back to the original point before the transformation.
This has to be the open-closed principle, the new simple factory class Cnewclassfactory, we declare the init () function as virtual function, if we want to add new computing objects, there are 2 ways:
The 5.1 user calls the Addoperationfunc () function in their own code to add.
5.2 inherits the new simple factory class, overriding the Init () function.
Big Talk design mode C + +-table-driven method to transform a simple factory