技术成神之路:设计模式(十二)模板方法模式
介绍
模板方法模式(Template Method Pattern)是一种行为设计模式,它定义了一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法模式使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
1.定义
模板方法模式是指在一个方法中定义一个算法的骨架,并将一些步骤的实现延迟到子类中。模板方法使得子类可以不改变算法的结构即可重定义算法的某些特定步骤。
2. 主要作用
- 在父类中定义算法的整体结构和步骤顺序。
- 将具体的步骤实现推迟到子类,让子类可以重新定义或扩展这些步骤的实现。
- 避免了在多个子类中重复编写相同的算法代码,从而实现代码复用。
3. 解决的问题
主要解决某些算法或程序在多个子类中有相似的逻辑结构,但实现细节各不相同的情况。通过模板方法模式,可以将这些相似的逻辑抽象到父类中,从而减少代码重复,提高系统可扩展性和可维护性。
比如在安卓中 BaseAdapter类提供了一些常见的适配器方法的实现,如getCount(),getItem(),getItemId(),以及getView()。getView()方法是一个模板方法,定义了如何生成和填充每个视图的基本过程,具体细节由子类实现。
4. 模式原理
包含角色:
- 抽象类(AbstractClass):定义一个或多个模板方法,并包含一个或多个抽象方法,这些方法由子类实现。
- 具体类(ConcreteClass):实现抽象类中的抽象方法,从而实现模板方法中的各个步骤。
UML类图:
示例代码:
// 抽象类
abstract class Beverage {
// 模板方法,定义制作饮料的步骤
public final void prepare() {
boilWater();
brew();
pourInCup();
addCondiments();
}
// 基本方法
private void boilWater() {
System.out.println("烧开水");
}
// 基本方法
private void pourInCup() {
System.out.println("倒入杯中");
}
// 子类实现
protected abstract void brew();
// 子类实现
protected abstract void addCondiments();
}
// 具体类
class Tea extends Beverage {
@Override
protected void brew() {
System.out.println("泡茶");
}
@Override
protected void addCondiments() {
System.out.println("加柠檬");
}
}
class Coffee extends Beverage {
@Override
protected void brew() {
System.out.println("冲咖啡");
}
@Override
protected void addCondiments() {
System.out.println("加糖和牛奶");
}
}
// 使用
public class TemplateMethodPatternDemo {
public static void main(String[] args) {
Beverage tea = new Tea();
tea.prepare();
Beverage coffee = new Coffee();
coffee.prepare();
}
}
很容易理解,感觉就像活字印刷一样,事先做好模板,方便后续直接使用!
5. 优缺点
优点:
- 代码复用:通过模板方法模式,可以将相同的代码放在抽象类中,减少重复代码。
- 易于维护:操作步骤在一个地方定义,修改时只需要修改模板方法,不需要修改每个子类。
- 扩展性强:添加新步骤时,只需要在子类中实现新的抽象方法即可,不影响其他子类。
缺点:
- 增加类数:每个具体实现都需要一个子类,类的数量会增加。
- 灵活性受限:在模板方法中定义的操作步骤是固定的,子类只能通过实现抽象方法来定制行为,不能改变模板方法的结构。
6. 应用场景
- 代码复用:多个类有相似的操作步骤,但细节实现不同时,可以将共同步骤提取到抽象类中。
- 程序初始化:在程序启动时,如果有固定的初始化步骤(加载配置、建立连接、启动服务等)。
- 控制流程:有固定的执行流程,如自动化测试框架。
在安卓中,像 Activity生命周期管理、自定义View绘制、RecyclerView.Adapter、AsyncTask… 都运用了模板方法。
- Activity提供的一些模板方法(如onCreate、onStart、onResume等)
- 自定义View时,可以通过重写onDraw方法来实现自己的绘制逻辑
- RecyclerView.Adapter类定义了的模板方法(如onCreateViewHolder、onBindViewHolder、getItemCount)
- AsyncTask 需要重写doInBackground和onPostExecute方法来定义异步任务的具体逻辑。
可以说模板方法在我们开发中随处可见。
7. 总结
模板方法模式通过在抽象类中定义一个操作的模板,而将具体步骤的实现留给子类,从而实现代码复用和灵活扩展。模板方法模式适用于那些需要在多个子类中共享相同操作步骤的场景。尽管它简化了代码结构,但也可能导致类的数量增多,灵活性受限。在实际应用中,模板方法模式常用于框架设计和具有固定算法结构的场景中。