模板方法模式
来源:互联网 发布:流行朋克知乎 编辑:程序博客网 时间:2023/12/03 10:01
定义
在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
通俗理解就是:在一个基类里面,定义了一个算法的流程(里面调用了很多方法),其中一些方法是基类已经实现的,一些是需要具体子类或实现类来实现的,还有一下是钩子(允许子类或实现类重写,如果不重写就按默认的执行),那么那个基类的流程方法就是模板方法。即算法框架的轨迹已经定义好了,部分实现允许按实际情况自己定义。模块方法模式在框架的架构中大量使用。
生活案例
在一个饮料冲泡的流程中,对于不同的饮料,很多方法都是相同的,只有部分实现是根据不同的饮料来实现的。所以可以定义一个基类:(prepareRecipe()为模板方法)
其中boilWater()和pourInCup()是每种饮料都需要的,所以基类来实现这两种方法,brew()和addCondiments()是根据不同饮料来实现的,所以定义为抽象类,需要子类来实现。
public abstract class CaffeineBeverage { final void prepareRecipe() {boilWater();brew();pourInCup();addCondiments();} abstract void brew(); abstract void addCondiments(); void boilWater() {System.out.println("Boiling water");} void pourInCup() {System.out.println("Pouring into cup");}}
咖啡类(茶类类似,就不贴代码了):
public class Coffee extends CaffeineBeverage {public void brew() {System.out.println("Dripping Coffee through filter");}public void addCondiments() {System.out.println("Adding Sugar and Milk");}}
钩子的定义:钩子是一种被声明在抽象类中的方法,但只有空的或者默认的实现。钩子的存在,可以让子类有能力对算法的不同点进行挂钩。要不要挂钩,由子类自行决定。
所以在饮料冲泡的流程中,对于要不要加入调料(即addCondiments)应该可以选择。
所以修改后的基类是:
public abstract class CaffeineBeverageWithHook { void prepareRecipe() {boilWater();brew();pourInCup();if (customerWantsCondiments()) {addCondiments();}} abstract void brew(); abstract void addCondiments(); void boilWater() {System.out.println("Boiling water");} void pourInCup() {System.out.println("Pouring into cup");} boolean customerWantsCondiments() {return true;}}
咖啡类:
public class CoffeeWithHook extends CaffeineBeverageWithHook { public void brew() {System.out.println("Dripping Coffee through filter");} public void addCondiments() {System.out.println("Adding Sugar and Milk");} public boolean customerWantsCondiments() {String answer = getUserInput();if (answer.toLowerCase().startsWith("y")) {return true;} else {return false;}} private String getUserInput() {String answer = null;System.out.print("Would you like milk and sugar with your coffee (y/n)? ");BufferedReader in = new BufferedReader(new InputStreamReader(System.in));try {answer = in.readLine();} catch (IOException ioe) {System.err.println("IO error trying to read your answer");}if (answer == null) {return "no";}return answer;}}
这样就可以让顾客自行选择要不要调料了,最重要的是这样使得了框架更灵活了,可以选择是否执行某个步骤,而不是按照一个死的流程来走。
java API中使用到的模板方法模式
这个是Arrays的sort()方法(就是排序功能),注意,这个例子里面没有用到像上面那个例子的抽象父类,而是用了一个静态方法(在这里也就是模板方法),这个静态方法有调用了本类的方法(即基类已经实现好的方法),也有调用需要实现类(这里不是子类了,而是接口的实现类)实现的方法。所以整个sort()流程的框架是定义好的,需要的是根据不同的实现类来实现部分具体的方法。
部分Arrays的源码:
public static void sort(Object[] a) { Object[] aux = (Object[])a.clone(); mergeSort(aux, a, 0, a.length, 0); }private static void mergeSort(Object[] src, Object[] dest, int low, int high, int off) {int length = high - low;// Insertion sort on smallest arrays if (length < INSERTIONSORT_THRESHOLD) { for (int i=low; i<high; i++) for (int j=i; j>low && ((Comparable) dest[j-1]).compareTo(dest[j])>0; j--) swap(dest, j, j-1); return; }
其中compareTo()方法是需要具体实现类来实现的,其他是基类Arrays已经实现的(有些常量和方法没贴出来,读者可以自行看java源码)。
那么具体实现类是怎样的:
public class Duck implements Comparable {String name;int weight; public Duck(String name, int weight) {this.name = name;this.weight = weight;} public String toString() {return name + " weighs " + weight;} public int compareTo(Object object) { Duck otherDuck = (Duck)object; if (this.weight < otherDuck.weight) {return -1;} else if (this.weight == otherDuck.weight) {return 0;} else { // this.weight > otherDuck.weightreturn 1;}}}
具体实现类需要实现Comparable接口,因为在基类算法流程里面需要将这个类强转为Comparable类型;具体实现类也需要实现compareTo()这个方法,流程里面也需要调用这个方法(即部分需要根据具体实现类来实现的方法)。
这样鸭子的排序流程就可以顺利进行了。
模板方法模式整体就是这样,大家如果有什么想法想交流交流,欢迎在下面评论哦。

5 0
- 深入浅出模板方法模式
- 模板方法模式
- 模板方法模式
- 模板方法模式
- 模板方法设计模式
- 模板方法模式
- 模板方法模式
- 模板方法模式
- 模板方法模式
- 模板方法模式
- 模板方法模式
- 模板方法模式
- 模板方法模式
- 模板方法模式
- TemplateMethod模板方法模式
- 模板方法模式
- 模板方法模式
- 模板方法模式
- POJ 3083 Children of the Candy Corn
- CF problem-56-E. Domino Principle 维护栈
- ZOJ-1257
- C++ Primer 【第四版】第八章 标准IO库
- Spring Aop实例
- 模板方法模式
- awk学习笔记
- 黑马程序员——网络编程
- uva11255 - Necklace 项链旋转翻转 置换
- HDU 3832 Earth Hour (最短路)
- C++ Primer 【第四版】第九章 顺序容器
- HDU 2298-Run(二分)
- window8.1 metro应用开发 之helloworld
- 黑马程序员--------------面向对象