设计模式 | 模板方法(Template Method)

What

  • 父类定义处理流程的框架,子类实现流程中各个功能的具体细节。
  • 设计原则:Do not call me, I will call you.

How

UML图

Template_Method

代码

以我们日常工作的日程安排为例

  1. 定义父类 Worker,里面定义了框架流程方法 dailyRountine

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    package one.wangwei.designpatterns.templatemethod;

    import lombok.extern.slf4j.Slf4j;

    @Slf4j
    public abstract class Worker {

    /**
    * 每日日程安排
    */
    public void dailyRountine() {
    String name = getName();
    getUp(name);
    eatBreakfast(name);
    goToWork(name);
    work(name);
    goBackHome(name);
    relax(name);
    sleep(name);
    System.out.println("\n");
    }

    /**
    * 获取姓名
    *
    * @return
    */
    protected abstract String getName();

    /**
    * 起床
    */
    public void getUp(String name) {
    log.info("{} 起床了", name);
    }

    /**
    * 吃早餐
    */
    public void eatBreakfast(String name) {
    log.info("{} 吃早餐", name);
    }

    /**
    * 去上班
    */
    public void goToWork(String name) {
    log.info("{} 要去上班了", name);
    }

    /**
    * 工作
    */
    protected abstract void work(String name);

    /**
    * 下班回家
    */
    public void goBackHome(String name) {
    log.info("{} 忙完工作,下班回家了", name);
    }

    /**
    * 放松休息
    */
    public void relax(String name) {
    log.info("{} 看美剧,放松一下", name);
    }

    /**
    * 入睡
    */
    public void sleep(String name) {
    log.info("{} 开始睡觉了", name);
    }

    }
  2. 定义子类 ProductManager,实现抽象方法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    package one.wangwei.designpatterns.templatemethod;

    import lombok.extern.slf4j.Slf4j;

    /**
    * 产品经理
    *
    * @author wangwei
    * @date 2018/05/08
    */
    @Slf4j
    public class ProductManager extends Worker {

    /**
    * 获取姓名
    *
    * @return
    */
    @Override
    protected String getName() {
    return "小伟";
    }

    /**
    * 工作
    *
    * @param name
    */
    @Override
    protected void work(String name) {
    log.info("{} 是位产品经理,主要的工作就是画产品原型", name);
    }
    }
  3. 定义子类 Programmer,实现抽象方法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    package one.wangwei.designpatterns.templatemethod;

    import lombok.extern.slf4j.Slf4j;

    /**
    * 程序员
    *
    * @author wangwei
    * @date 2018/05/08
    */
    @Slf4j
    public class Programmer extends Worker {

    /**
    * 获取姓名
    *
    * @return
    */
    @Override
    protected String getName() {
    return "小明";
    }

    /**
    * 工作
    *
    * @param name
    */
    @Override
    protected void work(String name) {
    log.info("{} 是名程序猿,主要的工作是编写程序", name);
    }

    /**
    * 放松休息
    *
    * @param name
    */
    @Override
    public void relax(String name) {
    log.info("{} 喜欢跑步来放松心情", name);
    }
    }
  4. 定义子类 UIDesigner,实现抽象方法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    package one.wangwei.designpatterns.templatemethod;

    import lombok.extern.slf4j.Slf4j;

    /**
    * UI 设计师
    *
    * @author wangwei
    * @date 2018/05/08
    */
    @Slf4j
    public class UIDesigner extends Worker {

    /**
    * 获取姓名
    *
    * @return
    */
    @Override
    protected String getName() {
    return "小美";
    }

    /**
    * 工作
    *
    * @param name
    */
    @Override
    protected void work(String name) {
    log.info("{} 是位UI设计师,每天的工作主要是设计UI界面", name);
    }

    /**
    * 放松休息
    *
    * @param name
    */
    @Override
    public void relax(String name) {
    log.info("{} 喜欢看韩剧来放松心情", name);
    }
    }
  5. 定义调用类 WorkerHelper

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    package one.wangwei.designpatterns.templatemethod;

    public class WorkerHelper {

    private Worker worker;

    public WorkerHelper(Worker worker) {
    this.worker = worker;
    }

    public void changeWorker(Worker worker) {
    this.worker = worker;
    }

    public void dailyRountine() {
    this.worker.dailyRountine();
    }
    }
  6. 运行

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    package one.wangwei.designpatterns.templatemethod;

    public class App {

    public static void main(String[] args) {
    WorkerHelper workerHelper = new WorkerHelper(new ProductManager());
    workerHelper.dailyRountine();

    workerHelper.changeWorker(new Programmer());
    workerHelper.dailyRountine();

    workerHelper.changeWorker(new UIDesigner());
    workerHelper.dailyRountine();
    }

    }



    // 输出如下信息:

    14:58:27.835 [main] INFO one.wangwei.designpatterns.templatemethod.Worker - 小伟 起床了
    14:58:27.842 [main] INFO one.wangwei.designpatterns.templatemethod.Worker - 小伟 吃早餐
    14:58:27.842 [main] INFO one.wangwei.designpatterns.templatemethod.Worker - 小伟 要去上班了
    14:58:27.842 [main] INFO one.wangwei.designpatterns.templatemethod.ProductManager - 小伟 是位产品经理,主要的工作就是画产品原型
    14:58:27.842 [main] INFO one.wangwei.designpatterns.templatemethod.Worker - 小伟 忙完工作,下班回家了
    14:58:27.842 [main] INFO one.wangwei.designpatterns.templatemethod.Worker - 小伟 看美剧,放松一下
    14:58:27.842 [main] INFO one.wangwei.designpatterns.templatemethod.Worker - 小伟 开始睡觉了


    14:58:27.842 [main] INFO one.wangwei.designpatterns.templatemethod.Worker - 小明 起床了
    14:58:27.843 [main] INFO one.wangwei.designpatterns.templatemethod.Worker - 小明 吃早餐
    14:58:27.843 [main] INFO one.wangwei.designpatterns.templatemethod.Worker - 小明 要去上班了
    14:58:27.843 [main] INFO one.wangwei.designpatterns.templatemethod.Programmer - 小明 是名程序猿,主要的工作是编写程序
    14:58:27.843 [main] INFO one.wangwei.designpatterns.templatemethod.Worker - 小明 忙完工作,下班回家了
    14:58:27.843 [main] INFO one.wangwei.designpatterns.templatemethod.Programmer - 小明 喜欢跑步来放松心情
    14:58:27.843 [main] INFO one.wangwei.designpatterns.templatemethod.Worker - 小明 开始睡觉了


    14:58:27.843 [main] INFO one.wangwei.designpatterns.templatemethod.Worker - 小美 起床了
    14:58:27.843 [main] INFO one.wangwei.designpatterns.templatemethod.Worker - 小美 吃早餐
    14:58:27.843 [main] INFO one.wangwei.designpatterns.templatemethod.Worker - 小美 要去上班了
    14:58:27.843 [main] INFO one.wangwei.designpatterns.templatemethod.UIDesigner - 小美 是位UI设计师,每天的工作主要是设计UI界面
    14:58:27.843 [main] INFO one.wangwei.designpatterns.templatemethod.Worker - 小美 忙完工作,下班回家了
    14:58:27.843 [main] INFO one.wangwei.designpatterns.templatemethod.UIDesigner - 小美 喜欢看韩剧来放松心情
    14:58:27.843 [main] INFO one.wangwei.designpatterns.templatemethod.Worker - 小美 开始睡觉了

JDK中的运用

参考资料

请我喝杯咖啡吧~