定义
通过定义一个模板结构,该结构中如果是子类都需要的方法则在模板抽象类中完成,如果是需要子类进行重写的方法(即多样性方法),则将方法的实现延迟到子类中(即定义为抽象方法)。
具体实现
这里我通过炒菜的过程来简单代表模板方法的实现
1.首先我们需要定义一个模板(模板一定是一个抽象类)
package design_pattern.template;
/**
* 模板方法模式
*
*/
public abstract class AbstractCook {
public void pourOil() {
System.out.println("倒入热油");
}
public void heatOil() {
System.out.println("起锅热油");
}
//放入蔬菜
public abstract void pourVegetable();
//放入调味料
public abstract void pourSauce();
public void cook() {
pourOil();
heatOil();
pourVegetable();
pourSauce();
System.out.println("烹饪完毕!");
}
}
2.根据不同的需求完成不同的实现,下面的例子是炒包菜和炒肉两种实现。
package design_pattern.template;
//炒包菜
public class FriedCabbage extends AbstractCook{
@Override
public void pourVegetable() {
System.out.println("放入切好的包菜");
}
@Override
public void pourSauce() {
System.out.println("加入酱油,盐等作料");
}
}
package design_pattern.template;
public class FriedMeat extends AbstractCook {
@Override
public void pourVegetable() {
System.out.println("放入辣椒,肉");
}
@Override
public void pourSauce() {
System.out.println("放入盐,耗油");
}
}
测试
背景描述:一个餐馆有两个菜(辣椒炒肉和炝包菜)
package design_pattern.template;
public class Restaurant {
public static void main(String[] args) {
AbstractCook friedCabbage = new FriedCabbage();
friedCabbage.cook();
System.out.println("---------------------------");
AbstractCook friedMeat = new FriedMeat();
friedMeat.cook();
}
}
输出结果:
倒入热油
起锅热油
放入切好的包菜
加入酱油,盐等作料
烹饪完毕!
---------------------------
倒入热油
起锅热油
放入辣椒,肉
放入盐,耗油
烹饪完毕!
优缺点
优点
1.易于扩展
即如果我们的餐厅想新加一个菜,只需要继承AbstractCook然后实现抽象方法即可。
2.实现了反向控制
通过将子类对象赋值给父类引用的方式,隐藏了子类具体的实现。
3.提高了代码重用率
比如一些子类拥有同样的方法实现,那么我们只需要在模板类中进行编写即可。
缺点
1.增加了系统的规模
因为如果想增加功能就需要继承模板类然后实现抽象方法,会使得类群变得十分庞大。