模板方法模式
2016-03-09 09:22
267 查看
【0】README
0.1)本文部分描述转自 “head first设计模式”,旨在学习 模板方法模式 的基础知识;
【1】看个荔枝——星巴克咖啡
1.1)星巴克咖啡冲泡法steps:
step1)把水煮沸;
step2)用沸水冲泡咖啡;
step3)把咖啡倒进杯子;
step4)加糖和牛奶;
1.2)星巴克茶冲泡法steps:
step1)把水煮沸;
step2)用沸水浸泡茶叶;
step3)把茶倒进杯子;
step4)加柠檬;
2)对以上问题的分析(Analysis)
A0)上述两种泡法都采用了相同的算法:
step1)把水煮沸;
step2)用热水泡咖啡或者茶;
step3)将饮料倒进杯子;
step4)在饮料内加入适当的调料;
A1)我们看到,step2 和 step4 处理的代码是一样的,所以将step2 和 step4 抽取到基类并具体实现,而基类只给出 step1 和 step3 的 抽象定义,由子类去具体实现;
A2)具体荔枝:
3)模板方法:定义了一个算法的steps,并允许子类的一个或多个steps提供实现;
Attention):这里要和我们的论文算法的实现联系起来,特别是对于机器学习的算法,其步骤都是一致的,可以结合模板方法模式来实现;(干货——将模板方法模式应用到机器学习的算法中)
4)钩子(hook): 钩子是一种被声明在抽象类中的方法,但只有空的实现或者默认的实现;(干货——引入钩子)
4.1)钩子的存在: 可以让子类有能力对算法的不同点进行挂钩。要不要挂钩,由子类自行决定;
4.2)使用钩子:我们在子类中覆盖它;
4.3)算法中某个操作是可选的,就用钩子;
【2】好莱坞原则
2.1)定义:别调用我们,我们会调用你;
2.2)在好莱坞原则下:我们允许底层组件将自己挂钩到系统上,但是高层组件会决定什么时候和怎样使用这些底层组件。换句话说,高层组件对待底层组件的方式是“别调用我们,我们会调用你”;
2.3)好莱坞原则和模板方法的连接
对上图的分析(Analysis):饮料的客户代码只依赖CaffeineBeverage 抽象,而不依赖于具体的Tea 或 Coffee。这可以减少整个系统的依赖;
【3】用模板方法排序
3.1)还记得 Comparable 和 compareTo() 方法吗?这种比较大小的算法,采用的就是 模板方法模式;(干货——经典荔枝,模板方法模式应用于Arrays.sort
排序)
3.2)看个荔枝(Arrays.sort):
对Arrays.sort方法的分析(Analysis):
A1)sort的设计者希望这个方法能应用于所有的数组,所以他们把sort()变成是静态的方法,这样一来,任何数组都可以使用这个方法。但是没有关系,他使用起来和它被定义在超类中是一样的。现在,还有一个细节要告诉你:因为 sort()并不是真正定义在超类中,所以sort方法需要知道你已经实现了这个compareTo()方法就可以了,否则就无法进行排序。
A2)方法调用轨迹:MyTest.main() -> Arrays.sort() -> ComparableTimSort.sort() -> ComparableTimSort.binarySort()
-> Comparable.compareTo()
【4】模板方法模式总述: 模板方法模式——在一个方法中定义了一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些steps;
0.1)本文部分描述转自 “head first设计模式”,旨在学习 模板方法模式 的基础知识;
【1】看个荔枝——星巴克咖啡
1.1)星巴克咖啡冲泡法steps:
step1)把水煮沸;
step2)用沸水冲泡咖啡;
step3)把咖啡倒进杯子;
step4)加糖和牛奶;
1.2)星巴克茶冲泡法steps:
step1)把水煮沸;
step2)用沸水浸泡茶叶;
step3)把茶倒进杯子;
step4)加柠檬;
2)对以上问题的分析(Analysis)
A0)上述两种泡法都采用了相同的算法:
step1)把水煮沸;
step2)用热水泡咖啡或者茶;
step3)将饮料倒进杯子;
step4)在饮料内加入适当的调料;
A1)我们看到,step2 和 step4 处理的代码是一样的,所以将step2 和 step4 抽取到基类并具体实现,而基类只给出 step1 和 step3 的 抽象定义,由子类去具体实现;
A2)具体荔枝:
package com.designpattern.chapter8; 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"); } }
package com.designpattern.chapter8; 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"); } }
package com.designpattern.chapter8; public class Tea extends CaffeineBeverage { public void brew() { System.out.println("Steeping the tea"); } public void addCondiments() { System.out.println("Adding Lemon"); } }
3)模板方法:定义了一个算法的steps,并允许子类的一个或多个steps提供实现;
Attention):这里要和我们的论文算法的实现联系起来,特别是对于机器学习的算法,其步骤都是一致的,可以结合模板方法模式来实现;(干货——将模板方法模式应用到机器学习的算法中)
4)钩子(hook): 钩子是一种被声明在抽象类中的方法,但只有空的实现或者默认的实现;(干货——引入钩子)
4.1)钩子的存在: 可以让子类有能力对算法的不同点进行挂钩。要不要挂钩,由子类自行决定;
4.2)使用钩子:我们在子类中覆盖它;
4.3)算法中某个操作是可选的,就用钩子;
package com.designpattern.chapter8; public abstract class CaffeineBeverageWithHook { final 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; } } }
【2】好莱坞原则
2.1)定义:别调用我们,我们会调用你;
2.2)在好莱坞原则下:我们允许底层组件将自己挂钩到系统上,但是高层组件会决定什么时候和怎样使用这些底层组件。换句话说,高层组件对待底层组件的方式是“别调用我们,我们会调用你”;
2.3)好莱坞原则和模板方法的连接
对上图的分析(Analysis):饮料的客户代码只依赖CaffeineBeverage 抽象,而不依赖于具体的Tea 或 Coffee。这可以减少整个系统的依赖;
【3】用模板方法排序
3.1)还记得 Comparable 和 compareTo() 方法吗?这种比较大小的算法,采用的就是 模板方法模式;(干货——经典荔枝,模板方法模式应用于Arrays.sort
排序)
3.2)看个荔枝(Arrays.sort):
package com.designpattern.chapter8; public class Duck implements Comparable<Duck>{ String name; int weight; public Duck(String name, int weight) { this.name = name; this.weight = weight; } @Override public int compareTo(Duck o) { if(this.weight > o.weight) return -1; else if(this.weight == o.weight) return 0; else return 1; } @Override public String toString() { return "name: " + name + "weight: " + weight; } }
package com.designpattern.chapter8; import java.util.Arrays; public class MyTest { public static void main(String[] args) { Duck[] ducks = { new Duck("nihao9",9), new Duck("nihao10",10), new Duck("nihao8",8) }; Arrays.sort(ducks); for (Duck duck : ducks) { System.out.println(duck); } } }
对Arrays.sort方法的分析(Analysis):
A1)sort的设计者希望这个方法能应用于所有的数组,所以他们把sort()变成是静态的方法,这样一来,任何数组都可以使用这个方法。但是没有关系,他使用起来和它被定义在超类中是一样的。现在,还有一个细节要告诉你:因为 sort()并不是真正定义在超类中,所以sort方法需要知道你已经实现了这个compareTo()方法就可以了,否则就无法进行排序。
A2)方法调用轨迹:MyTest.main() -> Arrays.sort() -> ComparableTimSort.sort() -> ComparableTimSort.binarySort()
-> Comparable.compareTo()
【4】模板方法模式总述: 模板方法模式——在一个方法中定义了一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些steps;
相关文章推荐
- 查经 民数记3章 利未人
- HUST 1605 Gene recombination(广搜,位运算)
- 使用logback.xml配置来实现日志文件输出
- HUST 1605 Gene recombination(广搜,位运算)
- 复利计算1.0,2.0,3.0,4.0,5.0
- 学习进度条
- 学习进度条
- HDU 4965 Fast Matrix Calculation 矩阵快速幂
- 【FireMonkey】StyleBook使用方法
- 函数可重入性(Reentrancy)概念详解
- 如何使用新单位rem
- 移动应用统计平台
- TF-IDF与余弦相似性的应用(三):自动摘要
- Linux设备驱动之mmap设备操作
- 堆和栈的区别(转过无数次的文章)
- 83. Remove Duplicates from Sorted List
- 35. Search Insert Position
- iOS 国际化
- Mysql主从环境搭建
- win10怎样安装IIS