行为型:模板设计模式

模板设计模式是一种行为型设计模式,用于封装不变的算法流程,允许子类替换具体步骤。文中通过动物园游览的例子展示了如何使用模板模式,其中父类定义固定流程,子类实现个性化逻辑。张三和李四分别代表不同行为,通过继承父类并重写部分方法实现各自特色。模板方法通常为final,确保流程不可篡改,钩子方法允许子类有条件地扩展流程。模板模式提高了代码复用,但也可能导致类数量增加。
摘要由CSDN通过智能技术生成

模板设计模式的分析和例子

先抛出两个问题:

  • 模板设计模式是什么样的?
  • 我们应该怎么去用模板设计模式? 

为了帮助理解,举一个生活中例子来说明:

张三和李四是好朋友,周末相约各自带着家人动物园一日游。

周末,张三李四各自买票取票。张三买了普通票需要排队,李四由于常来办了VIP会员,直接走了快速通道。都进入动物园后,张三的孩子想去看大熊猫,而李四的孩子想去看大老虎,于是分开逛。最后一起离开动物园

分析下这个例子的人物的行为,可以将逛这个动物园的流程总结抽象如下:

  1. 买票取票
  2. 排队检票进入(VIP不需要排队)
  3. 看不同的动物(因人而异)
  4. 离开动物园

可以看出1、4是固定的流程,2是有触发条件的,3是个性化的。

如果以代码形式单独表现张三、李四的行为,按照以上的1、4的流程是必定会有重复代码出现。现在还只有张三、李四,如果后面还继续出现王五、牛大,那这个重复代码的体量将会变的很可观,我们怎么去解决这个问题呢?

我们可以利用Java的一个特性:继承,将通用的行为抽象到父类中,由父类决定流程的顺序,子类只关注自己的个性化内容。模板设计模式也是利用了这个特性。

模板设计模式的思想就是利用了Java的继承特性,将子类中通用的算法抽象到父类,关键的个性化逻辑交由子类完成,整个算法的执行顺序流程由父类控制

在模板模式(Template Pattern)中,一个抽象类公开定义了执行它的方法的方式/模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行

在模板模式中,有几个成员需要了解

  • 模板方法:通常是一个由 final 修饰的方法,其中的内容是抽象的算法,它做为一个骨架,决定了动作的顺序
  • 具体方法:通常用来定义默认执行的方法,比如上述流程中的买票、离开动物园
  • 抽象方法:每个子类都必须要实现的方法,一般用来给子类实现个性化的逻辑,比如上述流程中看不同的动物
  • 钩子方法:通常是一个空方法,由子类决定扩展与否,影响流程的走向

上面说了很多理论理解,下面上代码~

  • 首先将父类实现出来,抽象父类中模板方法 playZoo() 方法,定义了整个算法执行的流程;buyTickets() 、 play()commonOrVip() 是三个具体方法,由父类直接调用,子类不关注实现;commonOrVip() 具体方法比较特殊,它是由钩子方法 isVip() 确定执行流程的,而钩子方法的具体返回可以由子类选择是否控制,也就是说,子类可以通过钩子方法影响整体的执行流程的
public abstract class AbstractGoZoo {
    /**
     * 定义算法的骨架
     * 模板方法
     * 为了防止恶意操作,加上final方法
     */
    public final void playZoo() {
        buyTickets();
        commonOrVip();
        play();
        leaveZoo();
    }

    /**
     * 具体方法
     */
    private void leaveZoo() {
        System.out.println("离开动物园!");
    }

    /**
     * 抽象方法
     */
    protected abstract void play();

    /**
     * 具体方法
     */
    private void commonOrVip() {
        if (isVip()) {
            System.out.println("绿色通道!");
        } else {
            System.out.println("排队检票!");
        }
    }

    /**
     * 钩子方法
     */
    public boolean isVip() {
        return false;
    }

    /**
     * 具体方法
     */
    private void buyTickets() {
        System.out.println("买票!");
    }
}
  • 上张三的代码,该段代码只实现了 play() 抽象方法
public class ZhangSan extends AbstractGoZoo {

    @Override
    protected void play() {
        System.out.println("我们去看大熊猫!");
    }
}
  • 上李四的代码 ,该段代码实现了 play() 抽象方法,重写了钩子方法 isVip(),将会影响执行流程
public class Lisi extends AbstractGoZoo {
    @Override
    protected void play() {
        System.out.println("我们去看大老虎!");
    }

    @Override
    public boolean isVip() {
        return true;
    }
}
  •  看看执行结果

 从上面的代码和结果看,张三除了个性化看的动作外,对流程没有改变。李四不仅个性化了自己看的动作,还改变了检票的流程执行。


 总结

  1. 当有一类行为都有共通的逻辑时,我们可以使用模板设计模式,封装不变部分,扩展可变部分。行为方式由父类控制,子类控制具体实现
  2. 优点:提取公共代码,便于维护;缺点:每一个不同的实现都需要一个子类来实现,导致类的个数增加,使得系统更加庞大。
  3. 注意事项:模板方法,一般都使用final修饰,防止恶意重写模板方法

模板模式总体来说是对行为抽象和控制,所以属于设计模式中的行为型

写完,收工~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

吃你的西瓜皮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值