前言
其实模板方法模式我们经常使用,而且在我看来,可能是23个设计模式中最简单的一个了,但是可能大家都忘记概念了,此偏博文作为总结回顾。
毕竟,总结,永远都是没错的。
在软件开发中,我们经常会遇到知道大概要做什么事情,但是细节没定,或者说,确定了大体的样子后,其中某个步骤可能有多种情况,多种写法,甚至是容易经常更换。
这个时候,我们的模板方法模式便上场了。而且在源码库中,使用频率是极高的。
正题
- 定义
定义一个操作中的算法框架,而将一些步骤延迟道子类中,使得子类可以不改变一个算法的结构即可重新定义该算法的某些特定步骤。(其实,说清楚了就是抽象类的良好使用)
注意与策略模式的不同是,策略模式的主要思想是:使不同的算法可以被相互替换,而不影响客户端的使用。
- 使用场景
对一些复杂的算法进行分割,将其算法中固定不变的部分设计为模板方法和父类具体方法,而一些可以改变的细节由其子类来实现。即:一次性实现一个算法的不变部分,并将可变的行为留给子类来实现。
各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。
需要通过子类来决定父类算法中某个步骤是否执行,实现子类对父类的反向控制。
- 使用方法
其实就相当于是抽象类的使用,而其中的关键就是抽象, 抽象出什么样的方法给子类去实现,这才是核心。
来个demo吧
abstract class AbstractClass {
//模板方法
public void TemplateMethod() {
PrimitiveOperation1();
PrimitiveOperation2();
PrimitiveOperation3();
}
//基本方法—具体方法
public void PrimitiveOperation1() {
//实现代码
}
//基本方法—抽象方法
public abstract void PrimitiveOperation2();
//基本方法—钩子方法
public void PrimitiveOperation3() {
}
}
class ImplClassA extends AbstractClass{
@Override
public void PrimitiveOperation2() {
//具体实现
}
}
- 优缺点
优点
模板方法模式的主要优点如下:
(1) 在父类中形式化地定义一个算法,而由它的子类来实现细节的处理,在子类实现详细的处理算法时并不会改变算法中步骤的执行次序。
(2) 模板方法模式是一种代码复用技术,它在类库设计中尤为重要,它提取了类库中的公共行为,将公共行为放在父类中,而通过其子类来实现不同的行为,它鼓励我们恰当使用继承来实现代码复用。
(3) 可实现一种反向控制结构,通过子类覆盖父类的钩子方法来决定某一特定步骤是否需要执行。
(4) 在模板方法模式中可以通过子类来覆盖父类的基本方法,不同的子类可以提供基本方法的不同实现,更换和增加新的子类很方便,符合单一职责原则和开闭原则。
缺点
模板方法模式的主要缺点如下:
需要为每一个基本方法的不同实现提供一个子类,如果父类中可变的基本方法太多,将会导致类的个数增加,系统更加庞大,设计也更加抽象。
源码下的模板方法模式
很多很多的等待我们实现的抽象类都使用了该模式。比较常见的是 AsyncTask,其实Activity也是,我们在各大生命周期中执行自己的细节代码,而那些生命周期回调就可以称之为钩子方法。
private AsyncTask task = new AsyncTask() {
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected Object doInBackground(Object[] params) {
return null;
}
@Override
protected void onPostExecute(Object o) {
super.onPostExecute(o);
}
};
我们可以看到,onPreExecute,doInBackground,onPostExecute这些都是模板方法父类为我们提供的让我们写具体细节的代码,而至于这个异步任务是怎么执行的,怎么挨个调用的,由模板方法统一处理。
谢谢大家阅读,如有帮助,来个喜欢或者关注吧!
本文作者:Anderson/Jerey_Jobs
博客地址 : 夏敏的博客/Anderson大码渣/Jerey_Jobs
简书地址 : Anderson大码渣
CSDN地址 : Jerey_Jobs的专栏
github地址 : Jerey_Jobs