1. 模版方法模式介绍
在面向对象开发过程中,通常我们会遇到这样的一个问题:我们知道一个算法的关键步骤,并确定了这些步骤的执行顺序。但是某些步骤的具体实现是未知的,或者说某些步骤的实现与具体的环境相关。
例如: 去食堂吃饭一般都有这样的步骤:
1. 排队
2. 买饭
3. 吃饭
这三个步骤一般都是固定的,但是不同的菜,三个步骤的具体操作是不确定的。
不同的菜买不同的原料;不同的菜不同的切法;不同的菜不同的做法。
但是这三个步骤一定是固定的。
2. 模版方法模式的使用场景
- 多个子类有公有的方法,并且逻辑基本相同。
- 重要、复杂的算法,可以把核心算法设计为模板算法,周边的相关细节功能由各个子类实现。
- 重构时,模版方法模式是一个经常使用的模式,把相同的代码抽取到父类中,然后通过钩子函数约定其行为。
3. 模版方法模式的UML类图
角色介绍:
AbsTemplate: 抽象类,定义了一套算法框架
ConcreteImplA:具体实现类A
ConcreteImplB:具体实现了B
4. 模版方法模式的简单实现
下面用代码模拟食堂买饭的情景:
- (1)、定义一个抽象模版:
在eatDinner方法里面依次顺序执行三个方法。
public abstract class EatDinner {
protected void queue() {
System.out.println("排队");
}
protected void buy() {
System.out.println("买饭");
}
protected void eat() {
System.out.println("吃饭");
}
//市场吃饭的步骤
public final void eatDinner() {
queue();
buy();
eat();
}
}
- (2)、两个具体的实现类AEatDinner、BEatDinner:
public class AEatDinner extends EatDinner {
@Override
protected void queue() {
System.out.println("排在A队");
}
@Override
protected void buy() {
System.out.println("买双份");
}
@Override
protected void eat() {
System.out.println("在食堂吃");
}
}
BEatDinner:
public class BEatDinner extends EatDinner {
@Override
protected void queue() {
System.out.println("排在B队");
}
@Override
protected void buy() {
System.out.println("买一份");
}
@Override
protected void eat() {
System.out.println("带宿舍吃饭");
}
}
- (3)、测试类:
public class Client {
public static void main(String[] args) {
EatDinner aEatDinner= new AEatDinner();
EatDinner bEatDinner = new BEatDinner();
aEatDinner.eatDinner();
System.out.println("------");
bEatDinner.eatDinner();
}
}
5. 模版方法模式在Android源码中
在Android源码中,模版设计模式比较常见,Activity的生命周期本身就是一个模版设计模式,这里就不具体分析了,相信大家在开始学习Android的时候,都已经对Activity的生命周期有所了解。
6. 模版方法模式在Android开发中:
这点就简单说一下,我们在onCreate方法中定义一下三个方法,自定义生命周期,用来进行相应的操作:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initVariables();
initView();
initData();
}
//初始化变量
private void initVariables() {
}
//初始化View
private void initView() {
}
//初始化数据
private void initData() {
}
}
7.总结
- 模版方法比较常见,其目的就是对流程进行封装。封装不可变的,扩展可变的。