Design mode-template mode

Source: Internet
Author: User

Overview

In real life, a lot of things include a few implementation steps, such as dinner, no matter what to eat, usually contains a list of orders, eat, pay a few steps, usually the order of these steps is: Order –> eat –> pay. In these three steps, the order and the bill are the same, the biggest difference is the second step-what to eat? Eating noodles and eating feast can be very different, 1 shows:

In software development, there are sometimes similar situations where a method implementation requires multiple steps (like "treat"), some of which are fixed (like "Order" and "buy"), while some steps are not fixed and there is variability (like "eating"). In order to improve the reusability of code and the flexibility of the system, we can use a design pattern called template method pattern to design this kind of situation, in the template method pattern, the method corresponding to each step of implementing function is called Basic method (such as "order", "Eat" and "buy"), The method of calling these basic methods to define the execution order of the base method is called a template method (such as "treat"). In the template method mode, you can put the same code in the parent class, such as the template method "treat" and the basic Method "order" and "buy" implementation in the parent class, and for the basic method "eat", only a declaration in the parent class, put its implementation in different subclasses, in a subclass to provide "eat noodles" , while another subclass provides a "Eat feast" implementation. By using the template method pattern, on the one hand, it improves the reusability of code, on the other hand, it can take advantage of object-oriented polymorphism, select a specific subclass at run time, realize the complete "treat" method, improve the flexibility and expansibility of the system.

Defined

Template method Pattern: Defines the framework for an algorithm in an operation, and delays some steps into subclasses. The template method pattern allows subclasses to redefine some specific steps of the algorithm without altering the structure of an algorithm.

The template method pattern is a kind of inheritance-based code reuse technique, which is a kind of behavior-type pattern.
The template method pattern is the simplest type of behavioral design pattern, in which there is only an inheritance relationship between the parent class and the subclass in the structure. By using the template method pattern, you can encapsulate the implementation steps of some complex process in a series of basic methods, provide a method called template method in the abstract parent class to define the order of execution of these basic methods, and override some steps by its subclasses, so that the same algorithm framework can have different execution results. The template method pattern provides a template method to define the algorithm framework, and the implementation of some specific steps can be done in its subclasses.

Template schema Structure

Template method pattern structure is relatively simple, its core is abstract class and the design of the template method, its structure is 2:

As shown in Figure 2, the template method pattern consists of the following two roles:
(1) AbstractClass (abstract Class): Defines a series of basic operations (primitiveoperations) in an abstract class, which can be concrete or abstract, one step for each basic operation corresponding to the algorithm, You can redefine or implement these steps in its subclasses. At the same time, a template method is implemented in an abstract class to define the framework of an algorithm, which can invoke not only the basic methods implemented in the abstract class, but also the basic methods implemented in subclasses of the abstract class, and can also invoke methods in other objects.
(2) Concreteclass (specific subclass): It is a subclass of an abstract class used to implement the steps of an abstract basic operation declared in a parent class to complete a subclass-specific algorithm, or to override a specific basic operation already implemented in the parent class.

Pattern implementation

When implementing template method patterns, it is possible to collaborate between software architects who develop abstract classes and software designers who develop specific subclasses. A designer is responsible for giving the outline and framework of an algorithm, while others are responsible for the various logical steps of the algorithm. The method that implements these concrete logical steps is the basic method, and the method that summarizes these basic methods is the template method, and the name of the template method pattern comes out. The template methods and basic methods are described in detail below:

1. Template method

A template method is a method of defining a general algorithm or a total behavior in an abstract class that combines basic operational methods. This template method is defined in an abstract class and is completely inherited by the subclass without modification. The template method is a concrete method, which gives a top-level logical framework, and the logical component steps can be either concrete or abstract methods in an abstract class. Because the template method is a concrete method, the abstraction layer in the template method pattern can only be an abstract class, not an interface.

2. Basic methods

The basic method is the method of implementing each step of the algorithm and is part of the template method. The basic method can be divided into three kinds: abstract method, Concrete method (concrete methods) and hook method.

(1) Abstract method:

An abstract method is declared by an abstract class and implemented by its specific subclasses. An abstract method is identified in the C # language with the abstract keyword.

(2) Specific methods:

A concrete method is declared and implemented by an abstract class or a concrete class, and its subclasses can be overwritten or inherited directly.

(3) Hook method:

A hook method is declared and implemented by an abstract class or a concrete class, and its subclasses may be extended. Usually the implementation given in the parent class is an empty implementation (which can be defined as a virtual function using the virtual keyword), and the null implementation is the default implementation of the method, but the hook method can also provide a non-null default implementation.

In the template method pattern, there are two types of hooks: the first type of hook method can be "hook" with some concrete steps to implement different steps in the template method under different conditions, the return type of such hooks is usually type bool, such method name is Isxxx (), which is used to judge a condition. If the condition is met, a step is performed, otherwise it will not execute, as shown in the following code snippet:

……//模板方法publicvoidTemplateMethod() {Open();Display();//通过钩子方法来确定某步骤是否执行if (IsPrint()) {    Print();}}//钩子方法publicboolIsPrint(){    returntrue;}……

The Isprint () method in the code is the hook method, which determines whether the print () method executes, in general, the return value of the Hook method is true, if you do not want a method to execute, you can override the Hook method in its subclass, and change its return value to False, This type of hook method can control the execution of a method and constrain an algorithm.
There is also a kind of hook method is to implement the concrete method of the body is empty, subclasses can overwrite or inherit these hook methods as required, compared with abstract methods, the advantage of such hooks is that if the subclass does not overwrite the hook method defined in the parent class, the compilation can pass normally, but if the abstract method declared in the parent class is not overridden, Compilation will be an error.
In the template method pattern, the typical code for an abstract class is as follows:

AbstractClass AbstractClass {//Template Method Public void Templatemethod() {PrimitiveOperation1 ();        PrimitiveOperation2 (); PrimitiveOperation3 ();}//Basic methods-specific methods Public void PrimitiveOperation1() {//Implementation code}//Basic Method-abstract method     Public Abstract void PrimitiveOperation2();//Basic Method-Hook method Public Virtual void PrimitiveOperation3()   {  }}

In the abstract class, the template Method Templatemethod () defines the framework of the algorithm, invoking the basic method in the template method to implement the complete algorithm, each basic method such as PrimitiveOperation1 (), PrimitiveOperation2 () All of these are implemented as part of the algorithm, and for all subclasses the same basic method can provide a concrete implementation in the parent class, such as PrimitiveOperation1 (), otherwise the parent class is declared as an abstract method or a hook method, and different subclasses provide different implementations. such as PrimitiveOperation2 () and PrimitiveOperation3 ().
You can provide an implementation of an abstract step in a subclass of an abstract class, or you can override a specific method that has already been implemented in the parent class, and the typical code for a subclass is as follows:

class ConcreteClass extends AbstractClass   {  @overridepublicvoid PrimitiveOperation2()   {      //实现代码  }  @overridepublicvoid PrimitiveOperation3()   {      //实现代码  }  

In the template method pattern, because of object-oriented polymorphism, the subclass object will overwrite the parent object at run time, and the methods defined in the subclass will override the methods defined in the parent class, so the basic method of the subclass will override the basic method defined in the parent class at run time, and the hook method of the subclass will override the parent class's Hook method. Thus, the implementation of the parent class method can be constrained by the hook method implemented in the subclass to implement the subclass's reverse control of the behavior of the parent class.

Instance Application

The template method pattern is further studied and understood through an application example.

A software company to develop an interest calculation module for a bank's business support system, the interest calculation process is as follows:
(1) The system verifies the user information according to the account number and password, if the user information is wrong, the system displays the error prompt;
(2) If the user information is correct, according to the different types of users use different interest calculation formula to calculate interest (such as the current account and the regular account has different interest calculation formula);
(3) The system displays interest.
Try to design the interest calculation module using the template method pattern.

Through analysis, this example structure is shown in Figure 3.

In Figure 3, the account acts as an abstract class role, and Currentaccount and Savingaccount act as specific subclass roles.

(1) Account: A class of accounts that acts as an abstract class.

//account.csusingSystem;namespace templatemethodsample{AbstractClass Account {//Basic methods--specific methods         Public BOOL Validate(stringAccountstringPassword) {Console.WriteLine ("account: {0}", account); Console.WriteLine ("Password: {0}", password);//Analog login            if(account. Equals ("Zhang Mowgli") && password. Equals ("123456"))             {return true; }Else{return false; }        }//Basic Method--abstract method         Public Abstract void calculateinterest();//Basic methods--specific methods         Public void Display() {Console.WriteLine ("Show Interest!" "); }//Template Method         Public void Handle(stringAccountstringPassword) {if(! Validate (Account,password)) {Console.WriteLine ("Incorrect account or password!" ");return;            } calculateinterest ();        Display (); }    }}

(2) Currentaccount: A current account class that acts as a specific subclass.

//CurrentAccount.csusing System;namespace TemplateMethodSample{    class CurrentAccount : Account    {        //覆盖父类的抽象基本方法        publicoverridevoid CalculateInterest()         {            Console.WriteLine("按活期利率计算利息!");        }    }}

(3) Savingaccount: A recurring account class that acts as a specific subclass.

//SavingAccount.csusing System;namespace TemplateMethodSample{    class SavingAccount : Account    {        //覆盖父类的抽象基本方法        publicoverridevoid CalculateInterest()         {            Console.WriteLine("按定期利率计算利息!");        }    }}

(4) config file App. Config, which stores the class name of the specific subclass in the configuration file.

<?xml version="1.0" encoding="utf-8" ?><configuration>  <appSettings>    <add key="subClass" value="TemplateMethodSample.CurrentAccount"/>  </appSettings></configuration>

(5) Program: Client Test class

//program.csusingSystem;usingSystem.Configuration;usingSystem.Reflection; namespace templatemethodsample{     class  program {        Static voidMain (string[] args) {account account;//Read configuration file            stringSubclassstr = configurationmanager.appsettings["Subclass"];//Reflection Generation ObjectAccount = (account) Assembly.Load ("Templatemethodsample").            CreateInstance (SUBCLASSSTR); Account. Handle ("Zhang Mowgli","123456");        Console.read (); }    }}

Compile and run the program with the following output:

账号:张无忌密码:123456按活期利率计算利息!显示利息!

If you need to change the specific subclass, without modifying the source code, just modify the configuration file App. Config, for example to change the current account (Currentaccount) to a recurring account (saving accounts), Simply change the specific subclass stored in the configuration file Currentaccount to Savingaccount, as shown in the following code:

<?xml version="1.0" encoding="utf-8" ?><configuration>  <appSettings>    <add key="subClass" value="TemplateMethodSample.SavingAccount"/>  </appSettings></configuration>

Rerun the client program with the following output:

账号:张无忌密码:123456按定期利率计算利息!显示利息!

If you need to add a new specific subclass (new account type), the original code does not need to be modified, fully comply with the open and closed principle.

Use of the Hook method

In the template method pattern, a template method that defines the algorithm framework is provided in the parent class, as well as a series of abstract methods, specific methods, and hook methods, in which the introduction of the hook method allows subclasses to control the behavior of the parent class. The simplest hook method is the empty method, the code is as follows:

publicvirtualvoidDisplay() {   }

Of course, you can also define a default implementation in the Hook method, and if the subclass does not overwrite the hook method, the default implementation code of the parent class is executed.
Another hook method can be implemented to constrain other methods, the hook method usually returns a bool type, that is, to return true or false, to determine whether to execute a basic method, the following is an example of the use of this hook method.

A software company to provide a data graph display function for the sales management system, the implementation of this feature includes the following steps:
(1) Obtain data from the data source;
(2) Convert data to XML format;
(3) displaying data in XML format in a graphical way.
This feature supports multiple data sources and multiple chart displays, but all chart display operations are based on data in XML format, so it may be necessary to convert the data if the data obtained from the data source is already XML data without conversion.

Because the three step order of the data graph display function is fixed, and there is common code (such as data format conversion code) that satisfies the applicable conditions of the template method pattern, it can be designed using the template method pattern. Because the data format is different, the XML data can be directly displayed, and other formats of data need to be converted, so the Step (2) "Convert data to XML format" Implementation is uncertain, in order to solve this problem, you can define a hook method Isnotxmldata () To control the data conversion method. Through analysis, the diagram shows the basic structure of the function as shown in 4:

You can put public and framework code in the abstract parent class with the following code:

//dataviewer.csusingSystem;namespace templatemethodsample{AbstractClass Dataviewer {//Abstract method: Get Data         Public Abstract void GetData();//Specific method: Convert Data         Public void Convertdata() {Console.WriteLine ("To convert the data to XML format. "); }//Abstract method: Display Data         Public Abstract void Displaydata();//Hook method: Determine whether the data is in XML format         Public Virtual BOOL Isnotxmldata()        {return true; }//Template Method         Public void Process() {GetData ();//Data conversion if data is not in XML format            if(Isnotxmldata ())            {Convertdata ();        } displaydata (); }    }}

In the above code, a hook method Isnotxmldata () is introduced, whose return type is type bool, which is used in the template method to constrain the data conversion method Convertdata (), the default return value of the Hook method is true, The method can be overridden in subclasses according to the actual situation, where the specific subclass of the Xmldataviewer code for displaying XML format data is as follows:

//xmldataviewer.csusingSystem;namespace templatemethodsample{class Xmldataviewer:dataviewer {//Implement parent class method: Get Data         Public Override void GetData() {Console.WriteLine ("Gets the data from the XML file. "); }//Implement parent class methods: Display data, displayed by default in a histogram, and can be combined with bridging mode to improve         Public Override void Displaydata() {Console.WriteLine ("displays data in a histogram. "); }//Override the parent's Hook method         Public Override BOOL Isnotxmldata()        {return false; }    }}

In the specific subclass Xmldataviewer, the Hook Method Isnotxmldata () is overridden to return false, indicating that the data is in XML format without the need to perform a data conversion method Convertdata (), the client code is as follows:

//Program.csusing System;namespace TemplateMethodSample{    class Program    {        staticvoid Main(string[] args)        {            DataViewer dv;            new XMLDataViewer();            dv.Process();            Console.Read();        }    }}

The program runs the following results:

从XML文件中获取数据。以柱状图显示数据。
Summarize

Template method pattern is an inheritance-based code reuse technique, which embodies many important ideas of object-oriented, and is a more frequent mode. Template method patterns are widely used in framework design to ensure that the logical order of the processing flow is controlled by the parent class (such as the initialization of the framework, the setting of the test process, etc.).

Advantages

The main advantages of the template method pattern are as follows:
(1) formally define an algorithm in the parent class, and its subclasses to implement the details of the processing, the subclass implementation of the detailed processing algorithm does not change the algorithm in the order of execution of the steps.
(2) The template method pattern is a code reuse technique, which is very important in the design of the class library, it extracts the public behavior in the class library, puts the public behavior in the parent class, and implements different behaviors through its subclasses, which encourages us to use inheritance appropriately to implement code reuse.
(3) A reverse control structure can be implemented to determine whether a particular step needs to be performed by overriding the parent class's Hook method.
(4) In the template method pattern can be overridden by subclasses of the basic method of the parent class, different subclasses can provide different implementations of the basic methods, replacement and addition of new subclasses is convenient, in line with the principle of single responsibility and open and close.

Disadvantages

The main disadvantages of the template method pattern are as follows:
It is necessary to provide a subclass for the different implementations of each of the basic methods, and if there are too many variables in the parent class, it will result in an increase in the number of classes, a larger system, and a more abstract design, which can be designed in conjunction with bridging mode.

Applicable scenarios

You can consider using the template method pattern in the following situations:
(1) Some complex algorithms are segmented, the fixed parts of the algorithm are designed as template method and parent class concrete method, and some of the details can be changed by their subclasses. That is: one-time implementation of an invariant part of the algorithm, and the variable behavior is left to the subclass to achieve.
(2) The public behavior of each subclass should be extracted and centralized into a common parent class to avoid duplication of code.
(3) A subclass is required to determine whether a step in the parent class algorithm executes, implementing the subclass's reverse control of the parent class.

Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

Design mode-template mode

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.