什么是模板方法模式:
在一个方法中定义一个算法的骨架,将一些步骤延迟到子类中去实现,模板方法可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
模板方法把不变的行为搬到了父类中,去除了子类中重复的代码,实现了代码的复用。有的时候我们会遇到一系列步骤构成的过程需要执行,这个过程从高层次上看是相同的,但是有些步骤的实现可能不同,这个时候就应该考虑模板方法模式了。
比如我们要做两道菜:一道是肉末炒茄子,一道是西红柿炒蛋。
肉末茄子的做法是:
1.热锅
2.放油
3.放入肉末和茄子
4.炒5分钟
西红柿炒蛋的做法是:
1.热锅
2.放油
3.放入蛋和西红柿
4.炒3分钟
从高的层次可以看出,它们的烹调过程是类似的,而且有相同的步骤。下面我们就用模板方法将它们抽象出来。
热锅和放油这两个方法是相同的,我们可以把它们放到超类中去实现。而放入肉末和茄子与放入蛋和西红柿,都是放入佐料,我们可以给它抽象出一个方法accedeStuff(),同样,烹调的时间也抽象成一个方法cookSometime()
我们可以得出这样一个抽象类:
public abstract class Cook {
/**
* 抽象方法,由子类完成。加入食材
*
* */
public abstract void accedeStuff();
/**
* 抽象方法,由子类完成。烹调适当的时间
*
* */
public abstract void cookSometime();
/**
*
* 为什么叫模板方法,因为它就是一个方法。用来炒茄子或者西红柿。算法中的每个步骤都被一个方法代表者。
* 某些方法是由这个类来处理,比如热锅和加油。某些类是交给子类来实现的,这就需要将这个类声明为抽象的,
* 以便子类覆盖,
*
* */
public void cookTemplateMethod()
{
warmPan();
pourOil();
accedeStuff();
cookSometime();
}
/**
* 将相同的代码在超类中完成,热锅
*
* */
private void warmPan()
{
Log.e("*********Method1:", "warmPan");
}
/**
* 将相同的代码在超类中完成,倒油
*
* */
private void pourOil()
{
Log.e("*********Method2:", "pourOil");
}
}
2.实例化这个抽象类
CookTomato.java
/**
* 炒西红柿
*
* */
public class CookTomato extends Cook{
@Override
public void accedeStuff() {
Log.e("*********accedeStuff:", "egg and tomato");
}
@Override
public void cookSometime() {
Log.e("*********cookSometime:", "3 minutes");
}
}
CookAubergine.java
/**
* 炒茄子
*
* */
public class CookAubergine extends Cook{
@Override
public void accedeStuff() {
Log.e("*********accedeStuff:", "meat and aubergine");
}
@Override
public void cookSometime() {
Log.e("*********cookSometime:", "5 minutes");
}
}
即,我们在子类中实现这些抽象方法。
最后我们需要在MainActivity.java中进行测试:
MainActivity.java
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
CookAubergine cookAubergine = new CookAubergine();
CookTomato cookTomato = new CookTomato();
Log.d("-----------", "making aubergine");
cookAubergine.cookTemplateMethod();
Log.d("-----------", "making tomato");
cookTomato.cookTemplateMethod();
}
}
打印结果: