Turn http://www.jellythink.com/archives/407
In Gof's design model: The basics of reusable object-oriented software, the template method pattern is said to define an algorithmic skeleton in an operation, while delaying some steps into subclasses. Templatemethod allows subclasses to redefine some specific steps of the algorithm without changing the interface of an algorithm.
I'll combine this template approach pattern with an example of what I'm doing in a real-world development project. We have worked on a product that resembles a cloud-like file management client. For such a client, because there are three servers in the cloud, and the communication between each server and the external interface is not consistent, this requires the implementation of the client to shield the cloud server and interface differences, and provide a unified operating interface, so while implementing this client, We implemented a framework, a common framework for servers and interfaces, such as downloading files. Our implementation is probably as follows:
classfileoperation{ Public: BOOLDownloadFile (wchar_t *psrc, wchar_t *pDest) { if(!psrc | |!pdest)return false; if(! Dobegindownloadfile (PSRC, PDest))return false; if(! Dodownloadfile (PSRC, PDest))return false; if(! Doenddownloadfile (PSRC, PDest))return false; }protected: Virtual BOOLDobegindownloadfile (wchar_t *psrc, wchar_t *pDest); Virtual BOOLDodownloadfile (wchar_t *psrc, wchar_t *pDest); Virtual BOOLDoenddownloadfile (wchar_t *psrc, wchar_t *pDest);};classHttpfileoperation: Publicfileoperation{protected: Virtual BOOLDobegindownloadfile (wchar_t *psrc, wchar_t *pDest); Virtual BOOLDodownloadfile (wchar_t *psrc, wchar_t *pDest); Virtual BOOLDoenddownloadfile (wchar_t *psrc, wchar_t *pDest);};classSoapfileoperation: Publicfileoperation{protected: Virtual BOOLDobegindownloadfile (wchar_t *psrc, wchar_t *pDest); Virtual BOOLDodownloadfile (wchar_t *psrc, wchar_t *pDest); Virtual BOOLDoenddownloadfile (wchar_t *psrc, wchar_t *pDest);};
The process of downloading the file is: Call Dobegindownloadfile First, perform some actions before downloading the file, then call Dodownloadfile to implement the real file download, and finally call Doenddownloadfile to complete the file download cleanup. For any server, the process of downloading the file will not change. The Dobegindownloadfile, Dodownloadfile, and Doenddownloadfile are implemented internally by programmers based on specific cloud servers and externally exposed interfaces. When the final client goes through the file download operation, it can only be done by invoking the DownloadFile function. As you can see, in the above code, only DownloadFile is public, and the other operation functions are protected. This also means that the framework we complete exposes only downloadfile interfaces to the outside.
AbstractClass (abstract Class): Defines the primitive operations of the abstraction, and the specific subclasses redefine them to implement the steps of an algorithm. The main is to implement a template method, define an algorithm skeleton. The template method not only invokes primitive operations, it also invokes operations defined in AbstractClass or other objects.
Concreteclass (Concrete Class): Implements primitive operations to complete the steps associated with a particular subclass in the algorithm.
Because the steps of implementing an algorithm are redefined in the specific subclass Concreteclass, the constant algorithm flow is done in AbstractClass Templatemethod.
Use occasions
A template method is a basic technique for code reuse. They are particularly important in class libraries, which extract public behavior from the class library. When using template methods, it is important that the template method indicate which actions can be redefined and which must be redefined. To effectively reuse an abstract class, the subclass writer must clearly understand which operations are designed to be redefined.
Code implementation
Based on the above class diagram, this paper makes a simple implementation of the template method pattern. Since this mode is very simple, there is no more to talk about.
#include <iostream>using namespacestd;classabstractclass{ Public: voidTemplatemethod () {PrimitiveOperation1 (); cout<<"Templatemethod"<<Endl; PrimitiveOperation2 (); }protected: Virtual voidPrimitiveOperation1 () {cout<<"Default Operation1"<<Endl; } Virtual voidPrimitiveOperation2 () {cout<<"Default Operation2"<<Endl; }};classConcreteclassa: Publicabstractclass{protected: Virtual voidPrimitiveOperation1 () {cout<<"Concretea Operation1"<<Endl; } Virtual voidPrimitiveOperation2 () {cout<<"Concretea Operation2"<<Endl; }};classCONCRETECLASSB: Publicabstractclass{protected: Virtual voidPrimitiveOperation1 () {cout<<"Concreteb Operation1"<<Endl; } Virtual voidPrimitiveOperation2 () {cout<<"Concreteb Operation2"<<Endl; }};intMain () {AbstractClass*pabstracta =NewConcreteclassa; Pabstracta-Templatemethod (); AbstractClass*PABSTRACTB =NewCONCRETECLASSB; PABSTRACTB-Templatemethod (); if(PABSTRACTA)Deletepabstracta; if(PABSTRACTB)DeletePABSTRACTB;}
Recently, there is a job fair, you can bring your resume to apply. However, one of them did not accept the resume, but sent a resume to the candidate, which has basic information, educational background, work experience and other columns, so that the candidates fill in the required complete. When everyone gets the form, they start filling it out. What if the process is implemented with a program? One scenario is to use the template method pattern: Define the skeleton of an algorithm in an operation, and defer some steps into the subclass. The template method allows subclasses to redefine some specific steps of the algorithm without altering the structure of an algorithm. In our case, the operation is the process of filling out a resume, and we can define the algorithm skeleton of the operation in the parent class, and the specific implementation is done by the subclass. The UML diagram is given below.
where Fillresume () defines the skeleton of the operation, which in turn invokes the function implemented by the subclass. Equivalent to the actual process of each person completing a resume. The corresponding C + + code is then given.
#include <iostream> #include <string.h>using namespace Std;class resume{protected:virtual void Setp Ersonalinfo () {} virtual void Seteducation () {} virtual void Setworkexp () {} public:void Fillresu Me () {setpersonalinfo (); Seteducation (); Setworkexp (); }};class resumea:public resume{protected:void setpersonalinfo () {cout<< "A ' s Personalinfo" <<en dl } void Seteducation () {cout<< "A ' s Education" <<endl;} void Setworkexp () {cout<< "A ' s work Experience" <<endl;}}; Class Resumeb:public resume{protected:void setpersonalinfo () {cout<< "B ' s Personalinfo" <<endl;} void Seteducation () {cout<< "B ' s Education" <<endl;} void Setworkexp () {cout<< "B ' s work Experience" <<endl;}}; int main () {Resume *r1; R1 = new Resumea (); R1->fillresume (); Delete R1; R1 = new REsumeb (); R1->fillresume (); Delete R1; R1 = NULL; return 0;}
[design mode] Template method pattern templates