DesignPattern - 模板方法模式【行为型】

892 阅读3分钟

欢迎关注微信公众号:FSA全栈行动 👋

一、模板方法模式介绍

模板方法模式(Template Method)定义一个操作中的算法骨架,将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤,属于行为型模式

  • 核心组成

    • 抽象模板(Abstract Template):定义一个模板方法,这个模板方法一般是一个具体方法,给出一个顶级算法骨架,而逻辑骨架的组成步骤在相应的抽象操作中,推迟到子类实现
      • 模板方法:定义了算法的骨架,按某种顺序调用其包含的基本方法
      • 基本方法:是整个算法中的一个步骤,包括抽象方法和具体方法
    • 具体模板(Concrete Template):实现父类所定义的一个或多个抽象方法,它们是一个顶级算法逻辑的组成步骤
  • 应用场景

    • javaweb 里的 Servlet,HttpService 类提供了一个 service()方法
    • 有多个子类共有逻辑相同的方法,可以考虑作为模板方法
    • 设计一个系统时,知道了算法所需的关键步骤,且确定了这些步骤的执行顺序,但某些步骤的具体实现还未知,可以延迟到子类进行完成
  • 优点

    • 扩展性好,对不变的代码进行封装,对可变的进行扩展,符合 开闭原则
    • 提高代码复用性,将相同部分的代码放到抽象的父类中,将不同的代码放入不同的子类中
    • 通过一个父类调用其子类的操作,通过对子类的具体实现扩展不同的行为,实现了反射控制
  • 缺点

    • 每一个不同的实现都需要一个子类来实现,导致类的个数增加,会使系统变得复杂

补充:如果是 Android 开发,BaseActivity 就是一个抽象模板,onCreate() 就是模板方法,onCreate() 中通常会调用 initView()initEvent()initData(),这 3 个便是基本方法,可以是抽象方法,或者是具体方法。

二、模板方法模式代码实现

创建抽象模板:

/**
 * 抽象模板:项目管理
 *
 * @author GitLqr
 */
public abstract class AbstractProjectManager {

	/**
	 * 定义模板方法,声明final,防止子类覆盖,流程是固定的: 需求评审 - 设计 - 开发 - 测试 - 上线 - 运维
	 */
	public final void processProject() {
		review();
		design();
		coding();
		test();
		online();
	}

	/**
	 * 每个项目都需要评审
	 */
	public void review() {
		System.out.println("项目需求评审");
	}

	/**
	 * 每个项目都需要设计
	 */
	public void design() {
		System.out.println("UI UE进行设计");
	}

	/**
	 * 抽象方法,由具体子类进行实现,具体编码耗时不一样
	 */
	public abstract void coding();

	/**
	 * 抽象方法,由具体子类进行实现,测试有多种:自动化测试、安全测试、压力测试、手工测试
	 */
	public abstract void test();

	/**
	 * 抽象方法,由具体子类进行实现,上线有全量发布、灰度发布、停机发布
	 */
	public abstract void online();
}

创建具体模板:

/**
 * 具体模板:支付服务项目管理
 *
 * @author GitLqr
 */
public class PayServiceProjectManager extends AbstractProjectManager {

	@Override
	public void coding() {
		System.out.println("开发耗时30天");
	}

	@Override
	public void test() {
		System.out.println("功能测试,安全测试,压力测试");
	}

	@Override
	public void online() {
		System.out.println("全量上线");
	}
}

/**
 * 具体模板:用户服务项目管理
 *
 * @author GitLqr
 */
public class UserServiceProjectManager extends AbstractProjectManager {

	@Override
	public void coding() {
		System.out.println("开发耗时10天");
	}

	@Override
	public void test() {
		System.out.println("功能测试,压力测试,手工测试");
	}

	@Override
	public void online() {
		System.out.println("灰度发布,全量上线");
	}
}

使用:

public static void main(String[] args) {
    AbstractProjectManager projectManager;

    projectManager = new PayServiceProjectManager();
    projectManager.processProject();

    System.out.println("=================");

    projectManager = new UserServiceProjectManager();
    projectManager.processProject();
}

如果文章对您有所帮助, 请不吝点击关注一下我的微信公众号:FSA全栈行动, 这将是对我最大的激励. 公众号不仅有Android技术, 还有iOS, Python等文章, 可能有你想要了解的技能知识点哦~