Head First 设计模式 --8 模板方法模式 别找我,我会找你
模板方法模式:在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
设计原则:
1、封装变化
2、多用组合少用集成
3、针对接口变成而非实现
4、松耦合
5、类对修改关闭,对扩展开放
6、依赖抽象而飞具体类
7、只和朋友交谈(迪米特原则)
8、别找我,我会找你(好莱坞原则)
比较好理解,直接看代码(冲茶和咖啡的例子):
abstract class CaffeineBeverage { 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; } } class Tea extends CaffeineBeverage { @Override void brew() { System.out.println("Steeping the tea"); } @Override void addCondiments() { System.out.println("Adding Lemon"); } public boolean customerWantsCondiments() { return false; } } class Coffee extends CaffeineBeverage { @Override void brew() { System.out.println("Steeping the tea"); } @Override void addCondiments() { System.out.println("Adding Sugar and Milk"); } public boolean customerWantsCondiments() { return true; } } public class Test { public static void main(String[] args) { Tea myTea = new Tea(); myTea.prepareRecipe(); } }
类图:
模板就是一个方法,这个方法将算法定义成一组步骤,公共的部分基类直接实现,不同的部分子类重写抽象方法。
上面还有一个技巧是可以通过子类的方法来判断模板中是否要调用某个方法。如果子类不重写那个方法,走的就是基类中的方法。也就是可以重写也可以不重写判断方法。
基类一般都是抽象方法,一般情况下会有相同的方法,算法的方法一般定义成final的,因为这个相当于模板不允许子类覆盖。
设计原则【好莱坞原则:别调用我们,我们会调用你】。
好莱坞原则防止“依赖腐败”的方法,当高层组件调用底层组件,底层组件又调用高层组件等等。这种情况下没有人能搞懂系统是如何设计的。在好莱坞原则下,我们组件将自己挂到系统上,但是高层组件和决定什么时候和怎样使用这些低层组件。也就是高层组件对待低层组件的方式是“别调用我们,我们会调用你”。
好莱坞原则和依赖倒置原则有点关系,依赖倒置教我们尽量避免使用具体类,更多使用抽象。而好莱坞原则是一种设计框架或则组件的技巧,好让低层组件能够被挂钩进计算中,而且又不会让高层组件依赖低层组件。两者的目标都是解耦。让低层组件一点都不依赖高层组件并不可能,我们所能做的就是避免高层和低层组件之间有明显的环状依赖。