设计模式之 模板方法模式

模板方法模式(Template Method Pattern),在父类中定义了一个模板方法,和一系列抽象方法,模板方法中调用了一系列抽象方法,而这些抽象方法的实现放到了子类当中实现。

而在子类中,不能改变这个模板方法,只能实现父类定义的抽象方法,这就相当于在子类中,能赋予自己的不同行为和细节,但是父类的模板方法,规定了每个子类都要执行这样一组方法。也就是约定了总体行为,具体行为则各自实现。

比如,我们每个人每天上班的过程如下:

7点起床,吃早饭—》乘坐交通工具上班—》完成上午的工作—》吃午饭—》完成下午的工作—》乘坐交通工具下班—》吃晚饭

我们每个人的上班生活,差不多是这样,总结一下就是:

吃早饭—>上班—>吃午饭—>下班—>吃晚饭

我们都要吃早饭,但是每个人吃的早饭各不相同,张三早上吃油条,李四早上吃面条,所以映射成代码就相当于:

模板方法定义了一天的生活

void dailyLife() {
        
        breakfast();//吃早饭
        goOnTransport();//上班
        lunch();//吃午饭
        goOffTransport();//下班
        dinner();//吃晚饭
        
    }

这写方法则是抽象方法,等待子类取实现自己的行为。

我们来具体看代码:

1、定义抽象类,定义了模板方法和每天各种要做的事情

package com.itzhimei.study.design.template;

/**
 * www.itzhimei.com
 * 定义了每天生活的模板
 */
public abstract class AbstractTemplateDailyLife {

    /**
     * 定义了每天生活的模板
     * 每个人都要吃早饭、上班、吃午饭、下班、吃晚饭
     */
    public final void dailyLife() {
        System.out.println("----------------------------");
        breakfast();
        goOnTransport();
        lunch();
        goOffTransport();
        dinner();
        System.out.println("----------------------------");
    }

    /**
     * 早饭
     */
    abstract void breakfast();

    /**
     * 上班方式--乘坐哪种交通工具
     */
    abstract void goOnTransport();

    /**
     * 午饭
     */
    abstract void lunch();

    /**
     * 下班方式--乘坐哪种交通工具
     */
    abstract void goOffTransport();

    /**
     * 晚饭
     */
    abstract void dinner();
}

2、定义了张三和李四每天的生活,张三class和李四class继承了抽象父类

package com.itzhimei.study.design.template;

/**
 * 张三的日常生活
 */
public class PersonA extends AbstractTemplateDailyLife {
    @Override
    void breakfast() {
        System.out.println("张三早饭吃面包");
    }

    @Override
    void goOnTransport() {
        System.out.println("张三骑自行车上班");
    }

    @Override
    void lunch() {
        System.out.println("张三午饭吃盖饭");
    }

    @Override
    void goOffTransport() {
        System.out.println("张三骑自行车下班");
    }

    @Override
    void dinner() {
        System.out.println("张三晚饭吃饺子");
    }
}
package com.itzhimei.study.design.template;

/**
 * 李四的日常生活
 */
public class PersonB extends AbstractTemplateDailyLife {
    @Override
    void breakfast() {
        System.out.println("李四早饭吃油条");
    }

    @Override
    void goOnTransport() {
        System.out.println("李四上班坐地铁");
    }

    @Override
    void lunch() {
        System.out.println("李四午饭吃面条");
    }

    @Override
    void goOffTransport() {
        System.out.println("李四下班坐地铁");
    }

    @Override
    void dinner() {
        System.out.println("李四晚饭吃披萨");
    }
}

3、测试

package com.itzhimei.study.design.template;

/**
 * www.itzhimei.com
 * 模板方法模式--测试
 */
public class Client {

    public static void main(String[] args) {
        AbstractTemplateDailyLife zhangsan = new PersonA();
        AbstractTemplateDailyLife lisi = new PersonA();

        //我们看看张三和李四的日常生活
        zhangsan.dailyLife();
        lisi.dailyLife();
    }
}

输出结果:

----------------------------
张三早饭吃面包
张三骑自行车上班
张三午饭吃盖饭
张三骑自行车下班
张三晚饭吃饺子
----------------------------
----------------------------
张三早饭吃面包
张三骑自行车上班
张三午饭吃盖饭
张三骑自行车下班
张三晚饭吃饺子
----------------------------

涉及角色:

1、抽象角色:声明了模板方法和需要子类实现的抽象方法。

2、具体角色:继承了抽象类,实现了抽象方法,定义了自己的行为。

类关系图:

总结:

模板方法模式定义一个算法骨架,将一些具体实现推迟到子类中实现,模板方法可以使子类在不改变算法结构和逻辑的情况下,赋予新的行为。