类型:行为型设计模式
你有一套通用的算法逻辑,这些逻辑的执行顺序是固定的,但是算法中的某些具体步骤在不同的对象上需要不同的实现。这种情况下,模板方法模式可以很好地解决问题。
一、基本概念
模板方法模式(Template Method Pattern)是一种行为型设计模式, 它定义了一个算法的骨架,将一些步骤的实现延迟到子类。模板方法模式使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
模板方法模式的关键原则
1. 算法的框架在抽象类中:模板方法模式应在抽象类中定义算法的整体框架(即模板方法),而具体的步骤实现则应在子类中完成。
2. 避免在抽象类中添加具体逻辑:在抽象类中不应包含对具体类型的条件判断或其他业务逻辑,以确保子类可以扩展算法而不修改父类。
⚠️模版方法模式的注意事项
- 在spring下,模版方法模式中@Service注解是加在具体实现类上,而不是抽象模版类,因为具体类继承自抽象模版类,具体类才是最终需要被实例化的,所以将具体实现类交由Spring管理。
二、基本结构
模版方法模式由抽象类和具体类两部分组成:(图源自https://refactoringguru.cn/design-patterns/template-method)
三、简单框架
这个设计模式的实现框架十分简单:
1 定义模版类实现这个目标功能接口,在模版方法中定义算法骨架;(一般要加final关键字,避免子类重写)
- 用
protected
使得抽象方法对于子类可见,但不对外部公开,确保了设计的完整性和安全性。 - 注意,抽象模版类中的全局变量(比如仓储)应该设置为
protected
,如果设置为private
,子类就无法访问了。
// 模板类
abstract class AbstractClass {
// 模板方法,定义算法的骨架
public final void templateMethod() {
step1();
step2();
step3();
// 可以包括其他步骤...
}
// 基本操作(可变的步骤),子类必须实现
protected abstract void step1();
protected abstract void step2();
// 可选的步骤,子类可以覆盖也可以不覆盖
protected void step3() {
// 默认实现(如果有的话)
}
}
2 继承模版类定义具体类,实现抽象类中的抽象方法
// 具体类
class ConcreteClass extends AbstractClass {
@Override
protected void step1() {
System.out.println("Step 1 ");
}
@Override
protected void step2() {
System.out.println("Step 2 ");
}
@Override
protected void step3() {
System.out.println("Step 3");
}
}
四、实例
在一个抽奖系统中,要实现接口中的 performRaffle
方法:
- 首先让抽象类先实现接口,在实现类中给出抽奖算法的大体框架(责任链 + 逻辑树),将具体的责任链和逻辑树代码用抽象方法代表,待具体类中实现。
- 接着定义具体类,让其继承自模板类,实现模版类中定义的抽象方法,给出算法的具体逻辑。