吴志勇的博客 吴志勇的博客
  • h5

    • HTML5&CSS3
  • scss

    • css预处理语言
  • JavaScript

    • JavaScript教程
    • Ajax
    • ES6教程
    • NodeJS
    • Typescript
  • 框架

    • Jquery
    • VUE
    • React
  • Swing专题
  • java基础
  • javaweb
  • 框架
  • 数据库
  • netty
  • 设计模式
  • 微服务及架构
  • 云原生
  • maven
  • 单元测试
工具
我的
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

吴志勇

......
  • h5

    • HTML5&CSS3
  • scss

    • css预处理语言
  • JavaScript

    • JavaScript教程
    • Ajax
    • ES6教程
    • NodeJS
    • Typescript
  • 框架

    • Jquery
    • VUE
    • React
  • Swing专题
  • java基础
  • javaweb
  • 框架
  • 数据库
  • netty
  • 设计模式
  • 微服务及架构
  • 云原生
  • maven
  • 单元测试
工具
我的
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • Swing专题

  • java基础

  • javaweb

  • 框架

  • Maven
  • 单元测试
  • 动态代理
  • 数据库

  • netty

  • 设计模式

    • simple_factory
    • factory_method
    • abstract_factory
    • singleton
    • builder
    • prototype
    • adapter
    • decorator
    • facade
    • bridge
    • proxy
    • composite
    • flyweight
    • observer
    • command
    • state
    • chain_of_responsibility
    • template_method
      • 模式引入
        • 问题描述
        • 模式定义
        • 问题分析
      • 模式介绍
        • 解决方案
        • 代码实现
        • 结构组成
      • 模式评价
        • 适用场景
        • 实际应用
        • 优点缺点
    • strategy
    • interpreter
    • mediator
    • visitor
    • memento
    • iterator
  • 微服务及架构

  • 云原生

  • Velocity模板引擎
  • 后端
  • 设计模式
wuzhiyong
2025-01-13

template_method

# 模板方法模式

# 模式引入

# 问题描述

回想小时候的随堂测验,老师在黑板上抄题目,同学们在下面先抄题目,再做答案。经常有同学眼神不好,会把题目抄错。

但是在考试时,就不会出现这种情况。因为大家拿到的考试试卷都是一样的。这里的考试试卷类似于一个模板,提取了相同的部分。

# 模式定义

模板方法模式定义了一个操作中的算法的骨架,将一些步骤延迟到子类中。

子类可以按需重写方法实现,但调用将以抽象类中定义的方式进行。

# 问题分析

尽可能减少所有重复的代码。

# 模式介绍

# 解决方案

  • 对于不同的学生,只有给出的答案不同,其他内容全都一样;
    • 将所有的重复代码都上升到父类,使其称为子类的模板 --> 将公共的试题代码写到父类,试题和答案都继承于它;
    • 只将答案改成一个虚方法,给继承的子类重写;
  • 在客户端代码中,将子类变量的声明改成父类,利用多态实现代码复用。

# 代码实现

考题试卷的抽象类:

public abstract class TestPaper {
    public void testQuestion1() {
        System.out.println("杨过得到,后来给了郭靖,炼成倚天剑、屠龙刀的玄铁可能是[ ] a.球墨铸铁 b.马口铁 c.高速合金钢 d.碳素纤维");
        System.out.println("答案:" + answer1());
    }

    public void testQuestion2() {
        System.out.println("杨过、程英、陆无双铲除了情花,造成[ ] a.使这种植物不再害人 b.使一种珍稀物种灭绝了 c.破坏了那个生物圈的生态平衡 d.造成该地区沙漠化");
        System.out.println("答案:" + answer2());
    }

    public void testQuestion3() {
        System.out.println("蓝凤凰致使华山师徒、桃谷六仙呕吐不止,如果你是大夫,会给他们开什么药[ ] a.阿司匹林 b.牛黄解毒片 c.氟哌酸 d.让他们喝大量的生牛奶 e.以上全不对");
        System.out.println("答案:" + answer3());
    }

    protected abstract String answer1();

    protected abstract String answer2();

    protected abstract String answer3();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

学生甲抄试卷的具体类:

public class TestPaperA extends TestPaper {
    @Override
    protected String answer1() {
        return "b";
    }

    @Override
    protected String answer2() {
        return "c";
    }

    @Override
    protected String answer3() {
        return "a";
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

学生乙抄试卷的具体类:

public class TestPaperB extends TestPaper {
    @Override
    protected String answer1() {
        return "c";
    }

    @Override
    protected String answer2() {
        return "a";
    }

    @Override
    protected String answer3() {
        return "a";
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

客户端代码:

public class TemplateMethodMain {
    public static void main(String[] args) {
        System.out.println("学生甲抄的试卷:");
        TestPaper studentA = new TestPaperA();
        studentA.testQuestion1();
        studentA.testQuestion2();
        studentA.testQuestion3();

        System.out.println("学生乙抄的试卷:");
        TestPaper studentB = new TestPaperB();
        studentB.testQuestion1();
        studentB.testQuestion2();
        studentB.testQuestion3();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

执行结果:

学生甲抄的试卷:
杨过得到,后来给了郭靖,炼成倚天剑、屠龙刀的玄铁可能是[ ] a.球墨铸铁 b.马口铁 c.高速合金钢 d.碳素纤维
答案:b
杨过、程英、陆无双铲除了情花,造成[ ] a.使这种植物不再害人 b.使一种珍稀物种灭绝了 c.破坏了那个生物圈的生态平衡 d.造成该地区沙漠化
答案:c
蓝凤凰致使华山师徒、桃谷六仙呕吐不止,如果你是大夫,会给他们开什么药[ ] a.阿司匹林 b.牛黄解毒片 c.氟哌酸 d.让他们喝大量的生牛奶 e.以上全不对
答案:a
学生乙抄的试卷:
杨过得到,后来给了郭靖,炼成倚天剑、屠龙刀的玄铁可能是[ ] a.球墨铸铁 b.马口铁 c.高速合金钢 d.碳素纤维
答案:c
杨过、程英、陆无双铲除了情花,造成[ ] a.使这种植物不再害人 b.使一种珍稀物种灭绝了 c.破坏了那个生物圈的生态平衡 d.造成该地区沙漠化
答案:a
蓝凤凰致使华山师徒、桃谷六仙呕吐不止,如果你是大夫,会给他们开什么药[ ] a.阿司匹林 b.牛黄解毒片 c.氟哌酸 d.让他们喝大量的生牛奶 e.以上全不对
答案:a
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 结构组成

模板方法UML

  • AbstractClass:抽象类,也就是一个抽象模板,定义并实现了一个模板方法。这个模板方法一般是一个具体方法,给出了顶级逻辑的骨架;
  • ConcreteClass:子类,实现父类所定义的一个或多个抽象方法。每一个ConcreteClass都可以给出抽象方法的不同实现。

# 模式评价

# 适用场景

  • 有多个子类共有的方法,且逻辑相同;
  • 重要的、复杂的方法,可以考虑作为模板方法。

# 实际应用

  • Spring 中对 Hibernate 的支持,将一些已经定好的方法封装起来,比如开启事务、获取 Session、关闭 Session 等,程序员不重复写那些已经规范好的代码,直接丢一个实体就可以保存;
  • 在造房子的时候,地基、走线、水管都一样,只有在建筑的后期才有加壁橱加栅栏等差异;

# 优点缺点

优点:

  • 把不变的形为搬到超类,去除了子类中的重复代码,提供了很好的代码复用平台,便于维护;
  • 封装不变部分,扩展可变部分;
  • 行为由父类控制,子类实现;

缺点: 每一个不同的实现都需要一个子类实现,导致类的个数增加,使得系统更加庞大。

上次更新: 2025-02-06 00:56:14

← chain_of_responsibility strategy→

Copyright © 2020-2025 wuzhiyong
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式