模板方法模式概念
模板方法模式属于行为型模式,它定义一个操作中的算法的骨架,而将一些步骤推迟到子类当中实现。父类抽取并实现的是公共方法,对于可变方法,父类做的只是定义了可变行为的接口,具体实现留给子类去完成,实现对代码的重复利用。
模式中的角色
抽象类(AbstractClass):实现了模板方法,定义了算法的骨架。
具体类(ConcreteClass):实现抽象类中的抽象方法,已完成完整的算法。
模板方法类图
实例:
去饭馆吃饭,一般分可分为3个步骤,点菜、吃饭、买单,而每个人去吃都是这个步骤,不同得是点的菜、吃饭花的时间、花的钱不一样而已,所以可以将点菜、吃饭、买单这3个步骤分别写成3个方法,而把这3个方法放到一个模板方法里面。具体实现如下:
/* * 菜单实体类 * */ 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 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; } }
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 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)); } }我吃饭花了30分钟......
水煮牛肉:30.0
麻婆豆腐:10.0
本次吃饭共花费:40.0
使用场景
- 定义复杂的类很少做修改,但经常需要向其添加新的操作。
- 需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免让
这些操作”污染”这些对象的类,使用访问者模式将这些封装到类中。
优缺点
优点
- 1.好的扩展性,能在不修改结构元素情况下,为元素添加新功能;
- 2.好的复用性,通过访问者来定义整个对象结构统一的功能,从而提高复用程度;
- 3.分离无关行为,把相关的行为封装在一起,构成一个访问者,这样每一个访问者的功能都比较单一。
缺点
- 1.不适用于结构中类经常变化的情况
- 2.破坏封装性,具体元素对访问者公布细节