【设计模式】模板方法模式 ( 简介 | 适用场景 | 优缺点 | 代码示例 )

举报
韩曙亮 发表于 2022/01/12 23:51:04 2022/01/12
【摘要】 文章目录 一、模板方法模式简介二、模板方法模式适用场景三、模板方法模式优缺点四、模板方法扩展五、模板方法模式相关设计模式六、模板方法模式代码示例1、模板方法抽象类2、模板方法实现类 13、模板方法...





一、模板方法模式简介



模板方法模式 : 定义了一个 算法骨架 , 并允许 子类 为 一个或多个 步骤 提供实现 ;

模板方法模式 可以使 子类 在不改变 算法结构 的前提下 , 重新定义算法的某些步骤 ;


模板方法模式类型 : 行为型 ;





二、模板方法模式适用场景



模板方法模式适用场景 :

  • 父类视角 : 一次性 实现 一个算法 不变的部分 , 并将 可变部分 留给 子类 实现 ;
  • 子类视角 : 各个子类中 , 公共部分 被提取出来 , 集中到一个公共的父类中 , 避免代码重复 ;

模板方法模式的目的是 让 子类可以扩展具体实现固定方法的某个具体的步骤 ; 对于模板来说 , 是一套固定的算法 , 通过子类 可以扩展 固定算法中某些算法步骤 ;





三、模板方法模式优缺点



模板方法模式优点 :

  • 提高代码复用性 :相同部分代码 , 放在抽象的父类中 ;

  • 提高扩展型 :不同的代码 , 放在不同的子类中 , 通过对子类的扩展 , 增加新的行为 ;

  • 符合开闭原则 : 通过 父类 调用 子类的操作 , 通过 对子类的扩展 来 增加新的行为 ;

模板方法模式 将 不变的行为定义在父类中 , 去除子类的重复代码 , 体现其优势 , 提供了一个很好的代码复用平台 ;


模板方法模式缺点 :

  • 增加复杂性 : 类 数量增加 , 增加了系统复杂性 ; 引入了抽象类 , 对于每个实现 , 都需要定义一个子类 ;

  • 继承缺点 : 模板方法 主要 通过 继承实现 , 继承关系自身就有缺点 , 如果父类增加新的抽象方法 , 所有的子类都要修改一遍 ;





四、模板方法扩展



模板方法扩展 : 通过 钩子方法进行扩展 ;

  • 钩子方法 : 提供缺省的行为 , 子类可以在必要时进行扩展 ;

钩子方法 是 模板对子类更进一步开方和扩展 ;





五、模板方法模式相关设计模式



模板方法模式与工厂方法模式 : 工厂方法模板方法的一种特殊实现 ;


模板方法模式和策略模式 : 二者都 封装了算法逻辑 ;

  • 策略模式 的目的是 使 各种算法 之间可以 相互替换 , 并且不影响最终用户的使用 , 对终端用户透明 ;

  • 模板方法模式 是针对 一个算法流程 , 将其中某些不太一样的算法步骤 , 交给子类实现 ,


模板方法模式不会改变算法流程 , 策略模式是可以改变算法流程的 , 并且策略模式的策略之间可以相互替换 ;





六、模板方法模式代码示例



业务场景 : 把大象放进冰箱 ;


1、模板方法抽象类


package templatemethod;

public abstract class Fridge {
    /**
     * 模板方法 不能被修改 , 使用 final 修饰 , 不允许子类覆盖该方法
     *      防止子类修改模板方法的流程
     */
    protected final void store() {
        openDoor();
        closeDoor();

        // 这个钩子方法可以让子类控制模板方法的执行流程
        if (needColdStorage()) {
            codeStorage();
        }

        put();
    }

    /**
     * 该方法是不变的 , 不允许子类修改
     */
    final void openDoor() {
        System.out.println("打开冰箱门");
    }

    final void codeStorage() {
        System.out.println("打开冷藏功能");
    }

    /**
     * 钩子方法 , 子类可以进行覆盖
     *      将适当的权限开放给应用层 , 用于控制模板方法流程
     * @return
     */
    protected boolean needColdStorage() {
        return false;
    }

    /**
     * 抽象方法 , 需要子类进行实现
     */
    abstract void put();

    final void closeDoor() {
        System.out.println("关闭冰箱门");
    }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48

2、模板方法实现类 1


注意这个类 实现了 钩子方法 , 改变了模板方法的执行流程 ;

package templatemethod;

public class FishFridge extends Fridge {
    @Override
    void put() {
        System.out.println("把鱼放进冰箱");
    }

    @Override
    protected boolean needColdStorage() {
        // 需要冷藏存储
        return true;
    }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

3、模板方法实现类 2


package templatemethod;

public class ElephantFridge extends Fridge {
    @Override
    void put() {
        System.out.println("把大象放进冰箱");
    }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

4、测试类


package templatemethod;

public class Main {
    public static void main(String[] args) {
        // 把大象放到冰箱
        Fridge elephantFridge = new ElephantFridge();
        elephantFridge.store();

        System.out.println();

        // 把鱼放到冰箱
        Fridge fishFridge = new FishFridge();
        fishFridge.store();
    }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

执行结果 :

打开冰箱门
关闭冰箱门
把大象放进冰箱

打开冰箱门
关闭冰箱门
冷藏存放
把鱼放进冰箱

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

在这里插入图片描述

文章来源: hanshuliang.blog.csdn.net,作者:韩曙亮,版权归原作者所有,如需转载,请联系作者。

原文链接:hanshuliang.blog.csdn.net/article/details/119790988

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。