Patterns of template methods for Java design patterns

Source: Internet
Author: User

Note This blog excerpt from Qin Xiaobo teacher wrote "design pattern of Zen"

Template method Mode car factory made Hummer

Suppose we were a car company, and now we have customers coming and asking us to build Hummer! Since the superior down orders that will be built, but build Hummer you have to tell us what the car function ah, the customer said: "Can start the car, can stop the car, can ring, can run." "Well, the function came out and began to build the car." The class diagram is as follows:

The abstract Hummer model code is as follows:
public abstract class HummerModel {    /*    * 首先,这个模型要能够被发动起来,别管是手摇发动,还是电力发动,反正    * 是要能够发动起来,那这个实现要在实现类里了    */    public abstract void start();    //能发动,还要能停下来,那才是真本事    public abstract void stop();    //喇叭会出声音,是滴滴叫,还是哔哔叫    public abstract void alarm();    //引擎会轰隆隆地响,不响那是假的    public abstract void engineBoom();    //那模型应该会跑吧,别管是人推的,还是电力驱动的,总之要会跑    public abstract void run();}

In an abstract class, we define the qualities that a Hummer model must have: it can start, stop, the horn will ring, the engine can roar, and it can stop. But the Hummer implementations of each model are different.

The H1 model of the Hummer code is shown below:
public class HummerH1Model extends HummerModel {    //H1型号的悍马车鸣笛    public void alarm() {         System.out.println("悍马H1鸣笛...");    }    //引擎轰鸣声    public void engineBoom() {         System.out.println("悍马H1引擎声音是这样的...");    }    //汽车发动    public void start() {         System.out.println("悍马H1发动...");    }    //停车    public void stop() {         System.out.println("悍马H1停车...");    }    //开动起来    public void run(){        //先发动汽车        this.start();        //引擎开始轰鸣        this.engineBoom();        //然后就开始跑了,跑的过程中遇到一条狗挡路,就按喇叭        this.alarm();        //到达目的地就停车        this.stop();    }}

Everyone pay attention to the run () method, this is a summary of the method, a model of production success, always to the customer testing it, how to detect? "Is a mule is a horse, pull out to sneak away", this is a test method, let it run up! By using the run () method, all the functions of the model are tested.

The H2 model Hummer is shown in the following code.
public class HummerH2Model extends HummerModel {    //H2型号的悍马车鸣笛    public void alarm() {         System.out.println("悍马H2鸣笛...");    }    //引擎轰鸣声    public void engineBoom() {         System.out.println("悍马H2引擎声音是这样在...");    }    //汽车发动    public void start() {         System.out.println("悍马H2发动...");    }    //停车    public void stop() {         System.out.println("悍马H2停车...");    }    //开动起来    public void run(){        //先发动汽车        this.start();        //引擎开始轰鸣        this.engineBoom();        //然后就开始跑了,跑的过程中遇到一条狗挡路,就按喇叭        this.alarm();        //到达目的地就停车        this.stop();    }}

Well, the program is written here, has found the problem, the two implementation classes of the run () method is identical, the implementation of the run () method should appear in the abstract class, should not be on the implementation of the class, abstract is the generic encapsulation of all subclasses.
Note that in the software development process, if the same piece of code is duplicated two times, you need to be skeptical about the design, and the architect will clearly explain why the same logic appears two or more times.
OK, the problem is found and we need to change it immediately, as shown in the Modified class diagram:

Note that the run () method in the abstract class Hummermodel is changed from an abstract method to an implementation method, with the source code shown below.

Modified Abstract Hummer model
public abstract class HummerModel {    /*    * 首先,这个模型要能发动起来,别管是手摇发动,还是电力发动,反正    * 是要能够发动起来,那这个实现要在实现类里了    */    public abstract void start();    //能发动,还要能停下来,那才是真本事    public abstract void stop();    //喇叭会出声音,是滴滴叫,还是哔哔叫    public abstract void alarm();    //引擎会轰隆隆地响,不响那是假的    public abstract void engineBoom();    //那模型应该会跑吧,别管是人推的,还是电力驱动,总之要会跑    public void run(){        //先发动汽车        this.start();        //引擎开始轰鸣        this.engineBoom();        //然后就开始跑了,跑的过程中遇到一条狗挡路,就按喇叭        this.alarm();        //到达目的地就停车        this.stop();    }}
The task of the scene class is to show the production model to the customer, the scene class code is as follows:
public class Client {    public static void main(String[] args) {        //XX公司要H1型号的悍马        HummerModel h1 = new HummerH1Model();        //H1模型演示        h1.run();    }}
The results of the operation are as follows.

Hummer H1 Launch ... Hummer H1 engine sound is like this ... Hummer H1 Whistle ...
Hummer H1 Parking ...

At present customers just look at H1 model Hummer, no problem, production out, at the same time can run up to him to see. Very simple, so if I tell you that this is the template method mode you will not be very disdain? In this mode, too simple, I have been using it! Yes, you often use, but you do not know that this is the template method mode, those so-called Master can be very bull said: "Template method can be achieved", you also have to admire the look, wow, cattle, template method mode is what ah? This is the template method pattern.

note in order to prevent malicious operations, the generic template method is prefixed with the final keyword and is not allowed to overwrite. The basic method in the abstract template is designed as protected type, conforms to the Dimitri Law, does not need to expose the property or method as far as possible not to set to protected type. If the implementation class is not necessary, try not to extend access permissions in the parent class.

Usage scenarios for Template method patterns

Multiple subclasses have public methods, and the logic is essentially the same.

Important and complex algorithm, the core algorithm can be designed as a template method, the surrounding details of the function is implemented by each sub-class.

Refactoring, the template method pattern is a frequently used pattern, extracting the same code into the parent class, and then constraining its behavior through the hook function (see "Extension of Template Method pattern").

Extension of template Method pattern

So far, both models have been running stably, and suddenly one day, the leader hurried to find me: "See how you design, the car starts, the horn is crazy, noisy dead!" The customer proposed H1 model Hummer Horn wants it to ring, the H2 model Horn does not have the sound, changes quickly. ”
Their own trouble, will find a way to solve it, a little reflection, the solution has, first draw the class diagram as follows:

The class diagram changes appear to be small, adding an implementation method to the abstract class Hummermodel isalarm to determine whether each model of Hummer requires sound, which is covered by each implementation class, while the other basic methods are designed as protected types because they do not require external access. Its source code is as follows:

Expanded abstract template class
public abstract class HummerModel {    /*    * 首先,这个模型要能够被发动起来,别管是手摇发动,还是电力发动,反正    * 是要能够发动起来,那这个实现要在实现类里了    */    protected abstract void start();    //能发动,还要能停下来,那才是真本事    protected abstract void stop();    //喇叭会出声音,是滴滴叫,还是哔哔叫    protected abstract void alarm();    //引擎会轰隆隆的响,不响那是假的    protected abstract void engineBoom();    //那模型应该会跑吧,别管是人推的,还是电力驱动,总之要会跑    final public void run() {        //先发动汽车        this.start();        //引擎开始轰鸣        this.engineBoom();        //要让它叫的就是就叫,喇嘛不想让它响就不响        if(this.isAlarm()){            this.alarm();        }        //到达目的地就停车        this.stop();    }    //钩子方法,默认喇叭是会响的    protected   boolean isAlarm(){    return true;    }}

In an abstract class, Isalarm is an implementation method. Its role is that the template method according to its return value determines whether to ring the horn, the subclass can overwrite the return value, because the H1 model of the horn is to let it ring, do not want it to ring without ringing, controlled by the person, the source code is as follows.

The extended H1 Hummer
public class HummerH1Model extends HummerModel {    private boolean alarmFlag = true;   //要响喇叭    protected void alarm() {         System.out.println("悍马H1鸣笛...");    }    protected void engineBoom() {         System.out.println("悍马H1引擎声音是这样的...");    }    protected void start() {         System.out.println("悍马H1发动...");    }    protected void stop() {         System.out.println("悍马H1停车...");    }    protected boolean isAlarm() {        return this.alarmFlag;    }    //要不要响喇叭,是由客户来决定的    public void setAlarm(boolean isAlarm){        this.alarmFlag = isAlarm;    }}

As long as the H1 model of the Hummer is called, the default is the horn ring, of course you can not let the horn ring, through the Isalarm (false) can be achieved. The Hummer of the H2 model has no horn sound, and its source code is shown below the code.

The extended H2 Hummer
public class HummerH2Model extends HummerModel {    protected void alarm() {         System.out.println("悍马H2鸣笛...");    }    protected void engineBoom() {         System.out.println("悍马H2引擎声音是这样的...");    }    protected void start() {         System.out.println("悍马H2发动...");    }    protected void stop() {         System.out.println("悍马H2停车...");    }    //默认没有喇叭的    protected boolean isAlarm() {        return false;    }}

The H2 model Hummer setting Isalarm () has a return value of false, that is, the speaker function is turned off. The scene class code is shown below.

Extended Scene Class
public class Client {    public static void main(String[] args) throws IOException{         System.out.println("-------H1型号悍马--------");         System.out.println("H1型号的悍马是否需要喇叭声响?0-不需要   1-需要");        String type=(new BufferedReader(new InputStreamReader(System.in))). HummerH1Model h1 = new HummerH1Model();        if(type.equals("0")){            h1.setAlarm(false);        }        h1.run();        System.out.println("\n-------H2型号悍马--------");        HummerH2Model h2 = new HummerH2Model();        h2.run();    }}

The operation requires interaction, first of all, the requirement to enter the H1 model of the Hummer if there is a sound, as follows:

-------H1型号悍马-------- H1型号的悍马是否需要喇叭声响?0-不需要 1-需要输入“0”后的运行结果如下所示:-------H1型号悍马-------- H1型号的悍马是否需要喇叭声响?0-不需要 1-需要0悍马H1发动... 悍马H1引擎声音是这样的... 悍马H1停车...-------H2型号悍马-------- 悍马H2发动... 悍马H2引擎声音是这样的... 悍马H2停车...

The results of the operation after entering "1" are as follows:

-------H1型号悍马-------- H1型号的悍马是否需要喇叭声响?0-不需要 1-需要    1悍马H1发动...悍马H1引擎声音是这样的...悍马H1鸣笛...悍马H1停车...-------H2型号悍马-------- 悍马H2发动... 悍马H2引擎声音是这样的... 悍马H2停车...

See no, the H1 model of the Hummer is the customer's own control whether to horn, that is to say, external conditions change, affecting the implementation of the template method. The return value of Isalarm in our abstract class is the result of the execution of the template method, which is called the hook method. With the Hook method template method is perfect, you can think of a method of a subclass of the return value determines the execution of the public part of the results, is not very attractive ah!

Template method pattern is to call the basic method in the template method according to certain rules and order, specific to the previous example, that is, the run () method in accordance with the specified order (first call Start (), then call Engineboom (), then call Alarm (), and finally call Stop () Other methods of this class are called, and the return value of the Isalarm () method determines the order of execution changes in run ().

Patterns of template methods for Java design patterns

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.