Template Method(模板方法)
1、意图:
定义一个操作中的算法骨架,而将一些步骤的具体实现延迟到子类中。TemplateMethod 使得子类可以不改变一个算法的结构(步骤)即可重定义该算法的某些特定步骤的具体实现。
2、模式中的角色
抽象类(AbstractClass):实现了模板方法,定义了算法的骨架。
具体类(ConcreteClass):实现抽象类中的抽象方法,已完成完整的算法。
3、模板方法类图
4、实例:
去饭馆吃饭,一般分可分为3个步骤,点菜、吃饭、买单,而每个人去吃都是这个步骤,不同得是点的菜、吃饭花的时间、花的钱不一样而已,所以可以将点菜、吃饭、买单这3个步骤分别写成3个方法,而把这3个方法放到一个模板方法里面。具体实现如下:
AbstractClass:
/**
* 餐馆吃饭抽象类
*
* @author xieke
* @since 15.7.28
*/
public abstract class Eat
{
// 所点菜的集合
protected List<Menu> list;
/**
* 吃饭模板方法
* @param list
* @return
*/
public double eat(List<Menu> list)
{
// 1.点菜
this.dianCai(list);
// 2.吃饭
this.chiFan();
// 3.买单
return this.maiDan();
}
/**
* 点菜
* @param list
*/
public void dianCai(List<Menu> list)
{
this.list = list;
}
/**
* 吃饭
*/
public abstract void chiFan();
/**
* 买单
* @return
*/
public double maiDan()
{
double money = 0.0;
for (Menu menu : list)
{
money += menu.getMoney();
}
return money;
}
}
ConcreteClass:
public class MeEat extends Eat
{
@Override
public void chiFan()
{
System.out.println("我吃饭花了30分钟......");
for(Menu menu : this.list){
System.out.println(menu.toString());
}
}
}
菜单实体类:
public class Menu
{
private String name;
private double money;
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public double getMoney()
{
return money;
}
public void setMoney(double money)
{
this.money = money;
}
public Menu(String name, double money)
{
this.name = name;
this.money = money;
}
@Override
public String toString()
{
return name + ":" + money;
}
}
测试类:
public class MainClass
{
public static void main(String[] args)
{
Eat eat = new MeEat();
List<Menu> list = new ArrayList<Menu>();
list.add(new Menu("水煮牛肉", 30.0));
list.add(new Menu("麻婆豆腐", 10.0));
System.out.println("本次吃饭共花费:"+eat.eat(list));
}
}
5、模式总结
5.1 优点
5.1.1 模板方法模式通过把不变的行为搬移到超类,去除了子类中的重复代码。
5.1.2 子类实现算法的某些细节,有助于算法的扩展。
5.1.3 通过一个父类调用子类实现的操作,通过子类扩展增加新的行为,符合“开放-封闭原则”。
5.2 缺点
5.2.1 每个不同的实现都需要定义一个子类,这会导致类的个数的增加,设计更加抽象。
5.3 适用场景
5.1 在某些类的算法中,用了相同的方法,造成代码的重复。
5.2 控制子类扩展,子类必须遵守算法规则。
转载请注明出处:http://xieke90.iteye.com/blog/2230939