设计模式详解(十一):模板方法——Template Method
Template Method 设计模式
1. 概述
Template Method 是一种行为设计模式,它定义了一个算法的框架,并允许子类在不改变算法结构的前提下重新定义算法中的某些步骤。
在 Template Method 模式中:
- 父类(抽象类)定义了算法的骨架(模板方法),包括一系列步骤。
- 子类可以覆盖其中的某些步骤,而不改变整体的流程。
Template Method 的定义
Template Method 模式是一种将算法的步骤结构固定下来的设计模式,通过一个模板方法(Template Method)定义算法的执行顺序,同时将部分步骤的实现延迟到子类中去完成。通俗来说,就是定义一个通用的流程框架,并允许子类根据需要填充其中的具体步骤。
模式的好处
- 代码复用:将通用的算法框架抽取到父类中,减少代码重复。
- 易于扩展:子类可以覆盖父类中的某些步骤,满足不同的业务需求,而不影响整体流程。
- 符合开闭原则:对扩展开放,对修改关闭,算法的整体结构不会轻易被改变。
适用场景
- 当多个子类之间存在相同的操作流程,但部分步骤的实现不同。
- 需要将算法的具体实现延迟到子类中,同时保持整体的逻辑结构一致。
- 需要复用算法的骨架,同时允许子类进行定制化操作。
UML 类图
解释:
AbstractClass
是抽象类,定义了templateMethod
,它调用了一系列步骤(step1
,step2
等)。ConcreteClass
是子类,实现了抽象类中定义的具体步骤。
2. 代码示例
2.1 基本示例
以下是一个简单的 Template Method 示例:
// 抽象类
abstract class TemplateMethod {
// 模板方法
public final void execute() {
step1();
step2();
optionalStep();
}
// 基本步骤,由子类实现
abstract void step1();
abstract void step2();
// 可选步骤,提供默认实现
void optionalStep() {
System.out.println("执行可选步骤");
}
}
// 具体实现类
class ConcreteClassA extends TemplateMethod {
@Override
void step1() {
System.out.println("ConcreteClassA: 执行步骤1");
}
@Override
void step2() {
System.out.println("ConcreteClassA: 执行步骤2");
}
}
class ConcreteClassB extends TemplateMethod {
@Override
void step1() {
System.out.println("ConcreteClassB: 执行步骤1");
}
@Override
void step2() {
System.out.println("ConcreteClassB: 执行步骤2");
}
@Override
void optionalStep() {
System.out.println("ConcreteClassB: 重写了可选步骤");
}
}
// 客户端代码
public class TemplateMethodDemo {
public static void main(String[] args) {
TemplateMethod templateA = new ConcreteClassA();
TemplateMethod templateB = new ConcreteClassB();
System.out.println("执行 ConcreteClassA:");
templateA.execute();
System.out.println("\n执行 ConcreteClassB:");
templateB.execute();
}
}
输出结果
执行 ConcreteClassA:
ConcreteClassA: 执行步骤1
ConcreteClassA: 执行步骤2
执行可选步骤
执行 ConcreteClassB:
ConcreteClassB: 执行步骤1
ConcreteClassB: 执行步骤2
ConcreteClassB: 重写了可选步骤
3. Android 中的应用
3.1 RecyclerView.Adapter
RecyclerView.Adapter
是一个典型的 Template Method 设计模式的应用。
onCreateViewHolder()
:创建 ViewHolder。onBindViewHolder()
:绑定数据到 ViewHolder。getItemCount()
:返回数据项数量。
Adapter
定义了完整的数据绑定流程,但子类负责实现各个具体步骤。
代码示例
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private List<String> data;
public MyAdapter(List<String> data) {
this.data = data;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(android.R.layout.simple_list_item_1, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.textView.setText(data.get(position));
}
@Override
public int getItemCount() {
return data.size();
}
// ViewHolder 内部类
public static class ViewHolder extends RecyclerView.ViewHolder {
TextView textView;
public ViewHolder(View itemView) {
super(itemView);
textView = itemView.findViewById(android.R.id.text1);
}
}
}
3.2 Activity 生命周期
Android 中 Activity
的生命周期回调函数也是 Template Method 模式的体现。
onCreate()
:Activity 被创建时调用。onStart()
:Activity 即将可见时调用。onResume()
:Activity 变为可交互状态时调用。
开发者在这些生命周期方法中实现具体逻辑,而 Activity
类则定义了整个流程。
3.3 Fragment 生命周期
Fragment
的生命周期同样是一个典型的 Template Method 模式的应用。
onAttach()
:Fragment 与 Activity 绑定时调用。onCreateView()
:创建 Fragment 视图时调用。onDestroyView()
:销毁视图时调用。
通过覆写这些方法,开发者可以根据需求自定义 Fragment 的行为。
4. 小结
Template Method 模式在 Android 中十分常见,通过它可以:
- 把算法的结构封装在父类中,保持代码复用性。
- 允许子类根据具体需求实现不同的步骤,增强灵活性。
关键点:
- 定义模板方法(
templateMethod
),确保算法的整体流程。 - 将具体的步骤延迟到子类实现。
通过本文的示例,我们了解了 Template Method 设计模式在 Android 中的实际应用,如 RecyclerView.Adapter
、Activity 生命周期
和 Fragment 生命周期
。这种模式有助于代码的扩展和维护,符合开闭原则(对扩展开放,对修改关闭)。