Behavioral patterns - Template Method (a)

The project source address: https: //github.com/ggb2312/JavaNotes/tree/master/design-pattern (design patterns relevant code and notes)

1. Definitions

It defines the skeleton of an algorithm and allows subclasses provide an implementation for one or more steps. Template methods such subclasses without changing the structure of the algorithm, some of the steps of the algorithm to redefine

2. Applicable scene

  • A part-time to achieve the same algorithm, and variable behavior left a subclass to achieve
  • Each subclass common behavior is extracted and concentrated to a common parent class, so as to avoid duplication of code

3. relevant design patterns

Template Method pattern and factory method pattern

  • Factory Method pattern is a special implementation template method pattern

Template Method pattern and strategy pattern

  • Strategy pattern is to make different algorithms can replace each other, and does not affect the use of the client. Execution process template method pattern defined algorithm, a different algorithm to the sub-class to implement

Example 4. Mode

4.1 General - Template Method

Background: learn cooking, cooking with garlic & Shredded cabbage heart **

(1) create an abstract template structure (Abstract Class)

Step cooking

public abstract class Abstract {
    //模板方法,用来控制炒菜的流程 (炒菜的流程是一样的-复用)
//申明为final,不希望子类覆盖这个方法,防止更改流程的执行顺序 
    final void cookProcess() {
        //第一步:倒油
        this.pourOil();
         //第二步:热油
        this.HeatOil();
        //第三步:倒蔬菜
        this.pourVegetable();
        //第四步:倒调味料
        this.pourSauce();
        //第五步:翻炒
        this.fry();
    }

//定义结构里哪些方法是所有过程都是一样的可复用的,哪些是需要子类进行实现的

    //第一步:倒油是一样的,所以直接实现
    void pourOil() {
        System.out.println("倒油");
    }

    //第二步:热油是一样的,所以直接实现
    void HeatOil() {
        System.out.println("热油");
    }

    //第三步:倒蔬菜是不一样的(一个下包菜,一个是下菜心)
//所以声明为抽象方法,具体由子类实现 
    abstract void pourVegetable();

    //第四步:倒调味料是不一样的(一个下辣椒,一个是下蒜蓉)
//所以声明为抽象方法,具体由子类实现 
    abstract void pourSauce();


    //第五步:翻炒是一样的,所以直接实现
    void fry() {
        System.out.println("炒啊炒啊炒到熟啊");
    }
}

(2) create a specific template (Concrete Class)

Fried concrete steps "Shredded cabbage" and "garlic cooking heart"

//炒手撕包菜的类
public class ConcreteClass_BaoCai extends Abstract {
    @Override
    public void pourVegetable() {
        System.out.println("下锅的蔬菜是包菜");
    }

    @Override
    public void pourSauce() {
        System.out.println("下锅的酱料是辣椒");
    }
}
//炒蒜蓉菜心的类
public class ConcreteClass_CaiXin extends Abstract {
    @Override
    public void pourVegetable() {
        System.out.println("下锅的蔬菜是菜心");
    }

    @Override
    public void pourSauce() {
        System.out.println("下锅的酱料是蒜蓉");
    }
}

(3) Testing

public class Test {
    public static void main(String[] args) {
        //炒 - 手撕包菜
        ConcreteClass_BaoCai BaoCai = new ConcreteClass_BaoCai();
        BaoCai.cookProcess();
        //炒 - 蒜蓉菜心
        ConcreteClass_CaiXin CaiXin = new ConcreteClass_CaiXin();
        CaiXin.cookProcess();
    }
}

Test Results

4.2 Extended - hook method

If you want fried two vegetables, one is not put seasoning, put a seasoning how to do it.
Template method in accordance with normal procedure is to write a class ConcreteClass_Qingcai_NotPourSauce Roasted rapeseed empty implementation pour seasoning method, write a class ConcreteClass_Qingcai achieve Roasted rapeseed pour seasoning method. Then hold fried vegetables used seasoning ConcreteClass_Qingcai_NotPourSauce, seasonings discharge fried vegetables
used ConcreteClass_Qingcai.

How to do it if you want to fry more vegetables?

You can add hook abstract template method in which, in the abstract implementation process, the hook function call to determine based on whether a certain step.

public abstract class Abstract {
    //模板方法,用来控制炒菜的流程 (炒菜的流程是一样的-复用)
//申明为final,不希望子类覆盖这个方法,防止更改流程的执行顺序 
    final void cookProcess() {
        //第一步:倒油
        this.pourOil();
        //d第二步:热油
        this.HeatOil();
        //第三步:倒蔬菜
        this.pourVegetable();
        //第四步:倒调味料
        
        // 这里是否需要倒调味料交由钩子方法来决定
        if (needPourSauce()) {
            this.pourSauce();
        }
        //第五步:翻炒
        this.fry();
    }


//定义结构里哪些方法是所有过程都是一样的可复用的,哪些是需要子类进行实现的

    //第一步:倒油是一样的,所以直接实现
    void pourOil() {
        System.out.println("倒油");
    }

    //第二步:热油是一样的,所以直接实现
    void HeatOil() {
        System.out.println("热油");
    }

    //第三步:倒蔬菜是不一样的(一个下包菜,一个是下菜心)
//所以声明为抽象方法,具体由子类实现 
    abstract void pourVegetable();

    //第四步:倒调味料是不一样的(一个下辣椒,一个是下蒜蓉)
//所以声明为抽象方法,具体由子类实现 
    abstract void pourSauce();


    //第五步:翻炒是一样的,所以直接实现
    void fry() {
        System.out.println("炒啊炒啊炒到熟啊");
    }

    /**
     * 我们就要给这个倒调味料声明一个钩子方法
     */
    protected boolean needPourSauce() {
        return true;
    }
}

So we only need a Roasted rapeseed class. Subclasses can selectively rewriting hook method, deciding whether to pour seasoning.

The advantages and disadvantages

advantage:

  • Improve reusability
  • Improve the scalability
  • In line with the principle of opening and closing

Disadvantages:

  • Increase the number of classes
  • It increases the complexity of system implementation
  • If the parent class to add a new abstract method, all subclasses must be changed again

6. The method of -JDK1.7 source and template extension of the frame

6.1 jdk

java.util.AbstractList template defines a set of algorithms, such as the get (), set (), etc., implemented by subclasses.

6.2 servlet

javax.servlet.http.HttpServlet template defines a set of algorithms, such as doGet (), doPost (), etc., implemented by subclasses. .

6.3 mybatis

org.apache.ibatis.executor.BaseExecutor

Guess you like

Origin www.cnblogs.com/gj-blog/p/10929517.html