模板方法模式(Template Method Pattern)
意图:定义一个操作中的算法(业务)的骨架, 而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法(业务)的结构即可重定义该算法的某些特定步骤.
主要解决:一些方法通用, 却在每一个子类都重新写了这一方法。
例如:
一个做饭的流程, 点火>烹饪>关火>洗锅
其中'点火'和'关火'是无论做什么菜流程都一样(通用)
而'烹饪'则是根据每种菜的做法而不同(延迟至子类实现)
'洗锅'则是可选的, 最后一道菜做完收锅(hook, )
关键点在于区分:
- 哪些方法是通用的, 在父类实现
- 哪些方法是不同的, 在父类抽象, 在子类中实现;
- 哪些方法属于hook, 在父类实现, 在子类中可选的调用;
in short 抽象类实现大流程, 具体细节(抽象方法)给子类实现
UML类图
代码实例
1.抽象父类(做菜)
- public abstract class AbstractCook {
- //做饭 统一的流程
- public final void doCook(){
- openFire();
- cooking();
- if(isFinal()){
- doFinal();
- }
- closedFire();
- }
- //钩子方法
- public boolean isFinal() {
- return false;
- }
- public void doFinal() {
- System.out.println("做完收锅!!");
- }
- protected abstract void cooking();
-
- protected void openFire() {
- System.out.println("点火, 开始做菜了");
- }
- protected void closedFire() {
- System.out.println("关火, 菜出锅了");
- }
- }
复制代码 2.具体子类(小龙虾和炒饭)
- public class Crayfish extends AbstractCook {
- @Override
- protected void cooking() {
- System.out.println("一份小龙虾!");
- }
- }
- public class FryRice extends AbstractCook {
- @Override
- protected void cooking() {
- System.out.println("一份炒饭!");
- }
- @Override
- public boolean isFinal() {
- return true;
- }
- }
复制代码 模板方法模式(Template Method Pattern) 总结
模板方法模式优缺点
优点:
- 在父类中形式化的定义一个算法, 而由它的子类来实现细节处理, 在子类实现详细的处理代码时, 并不会改变父类算法中步骤的执行顺序.
- 模板方法可以实现一种反向的控制结构, 通过子类覆盖父类的钩子方法, 来决定某一个特定步骤是否需要执行
- 在模板方法模式中可以通过子类来覆盖父类的基本方法, 不同的子类可以提供基本方法的不同实现, 更换和增加新的子类很方便, 符合单一职责原则和开闭原则.
缺点:
- 对每个不同的实现都需要定义一个子类, 这会导致类的个数增加, 系统更加庞大, 设计也更加抽象。
- 父类中的抽象方法由子类实现, 子类执行的结果会影响父类的结果, 这导致一种反向的控制结构, 它提高了代码阅读的难度。
模板方法模式适用场景
- 多个类有相同的方法并且逻辑可以共用时;
- 将通用的算法或固定流程设计为模板, 在每一个具体的子类中再继续优化算法步骤或流程步骤时;
- 重构超长代码时, 发现某一个经常使用的公有方法。
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |