模板方法模式
模板方法模式定义了一个算法的步骤,并允许子类别为一个或多个步骤提供其实践方式。让子类别在不改变算法架构的情况下,重新定义算法中的某些步骤。
UML:
角色说明:
AbstractClass:实现了模板方法,定义了算法骨架,子类需要实现抽象方法 operation1、2、3...
ConcreteClass:继承抽象类、实现父类中的抽象方法
Cast:以打饮料为例,大体步骤都相同:加冰 -> 糖浆 -> 果粒 -> 饮料 -> 打包呈递
AbstractClass:模板方法一般认为是功能完善的,为了不让子类覆写该方法,可以添加 final 修饰

1 public abstract class Drink { 2 void addIce() { 3 System.out.println("加冰块"); 4 } 5 6 abstract void fillDrink(); 7 8 void packing() { 9 System.out.println("打包呈递"); 10 } 11 12 public final void getDrink() { 13 addIce(); 14 fillDrink(); 15 packing(); 16 } 17 }
ConcreteClass:

1 // 可乐 2 public class Coke extends Drink { 3 @Override 4 void fillDrink() { 5 System.out.println("加可乐"); 6 } 7 } 8 9 // 雪碧 10 public class Sprite extends Drink { 11 @Override 12 void fillDrink() { 13 System.out.println("加雪碧"); 14 } 15 }
钩子方法:
由抽象类声明并且实现,子类可以选择加以扩展。通常抽象类会给出一个空的钩子方法,也就是没有实现的扩展。它和具体方法在代码上没有区别,不过是一种意识的区别;而它和抽象方法有时候也是没有区别的,就是在子类都需要将其实现的时候。而不同的是抽象方法必须实现,而钩子方法可以不实现。也就是说钩子方法为你在实现某一个抽象类的时候提供了可选项,相当于预先提供了一个默认配置。
例如:饮料默认是加冰的、但顾客可能需要去冰的饮料
实现类:

1 // 雪碧 2 public class Sprite extends Drink { 3 @Override 4 void addIce() { 5 // 空实现 6 } 7 8 @Override 9 void fillDrink() { 10 System.out.println("加雪碧"); 11 } 12 }
总结:
基本思想就是让父类实现算法,子类只需要实现不同的部分,使得修改算法只需要修改父类的模板方法或已经实现的步骤,子类会自动继承修改的部分。
最大程度上实现了代码的复用,既统一了算法,又增加了灵活性。
缺点:每个不同之处需要一个不同的实现类,使得类的数量增加,设计更加抽象。