Java行为型设计模式 —— 模板方法模式将大象塞入冰箱

一、引言

今今今今今今今今今天,小编所编写设计模式已经进入白热化状态了,之前介绍了创建型、结构型一共12种设计模式。

现在升级到行为型设计模式了,skr skr skr ~~~

行为型设计模式一共11种,那么今天就来说模板方法模式,这个模板方法设计模式相对来说还是比较好理解的。

二、模板方法基本介绍

有时候我们在功能开发过程当中,会发现新需求和之前的功能很类似,执行的流程都一样,可能就是其中某一个环节略有不同。但是如果全部重写不仅仅浪费时间(指的就是复制和粘贴哈哈哈哈),代码也太冗余了。

这个时候我们就可以考虑使用模板方法模式。

模板方法模式又叫模板模式,在一个抽象类定义了执行它的方法的模板,它的子类可以按需求重写方法实现,但调用将以抽象类中定义的方式进行。

举个例子,将大象放入冰箱,我们需要打开冰箱,把大象塞进去,再把冰箱关上对不对。其中打开冰箱、关闭冰箱这是公用的方法,因为不管你放什么东西,都需要这两个步骤。只是把大象塞进去需要交给子类去实现,因为冰箱可以放很多不同的东西,放什么由调用者决定。

这个抽象类就定义了这些方法,制定了这一套流程的模板,并且不可以改变,唯一可以改变的就是你要放入什么东西进去。

三、模板方法案例演示

我们就用刚刚说所的:将大象塞入冰箱 这个主题转化为代码演示一下。

这个就是我们的抽象类啦,里面定义了打开冰箱、关闭冰箱,并且还有一个抽象的添加方法,需要交给子类实现。

其中还有一个钩子方法:小时候闲的慌或者手痒痒喜欢没事打开下冰箱感受一下冷气,又关上。这个钩子方法就是干这个事情的,它可以控制是否需要添加。

这里默认是需要放入物品的,如果不想要执行这一步流程则可以重写这个钩子方法。

而在这个storing这个方法里面,定义了放入的整个流程并且是final类型不可被重写。

/**
 * @Auther: IT贱男
 * @Date: 2019/12/6 10:27
 * @Description: 定义存放冰箱的步骤
 */
public abstract class AStoring {

    /**
     * 存放物品
     */
    protected final void storing() {
        // 打开冰箱
        open();
        // 添加物品
        if (needAdd()) {
            add();
        }
        // 关闭冰箱
        close();
    }

    /**
     * 打开冰箱
     */
    final void open() {
        System.out.println("打开冰箱........");
    }

    /**
     * 关闭冰箱
     */
    final void close() {
        System.out.println("关闭冰箱........");
    }

    /**
     * 添加物品,放入什么物品由子类来决定
     */
    abstract void add();

    /**
     * 钩子方法
     *
     * @return
     */
    protected boolean needAdd() {
        return true;
    }

}

当然需要一个具体的子类来继承这个抽象类,实现这个添加方法。

/**
 * @Auther: IT贱男
 * @Date: 2019/12/6 10:36
 * @Description: 将大象放入冰箱
 */
public class StoringElephant extends AStoring {

    @Override
    void add() {
        System.out.println("把大象放入冰箱......");
    }

}
/**
 * @Auther: IT贱男
 * @Date: 2019/12/6 10:37
 * @Description:
 */
public class Client {

    public static void main(String[] args) {
        AStoring storing = new StoringElephant();
        storing.storing();
    }

}
打开冰箱........
把大象放入冰箱......
关闭冰箱........

假设现在来需求了,流程还是不变,可是放入的东西不太一样,

这里就能体现代码的代码的复用性,并且流程还是保持不变。 这里还可以使用钩子方法,不想放入就重写返回false。


/**
 * @Auther: IT贱男
 * @Date: 2019/12/7 16:20
 * @Description: 将香蕉放入冰箱
 */
public class StoringBanana extends AStoring {

    @Override
    void add() {
        System.out.println("把香蕉放入冰箱......");
    }

    @Override
    protected boolean needAdd() {
        return false;
    }

}

三、模板方法模式使用注意细节

每个设计模式有优点就肯定有相对应的缺点,冰箱能够存放的种类太多了,一个物品就需要一个子类来实现,这样就很容易导致类个数的增加,也就是类爆炸的现象。

在使用过程中一般模板方法都需要加上final的关键字,比如说我们这个案例就是storing()这个方法,不允许被子类重写。

那么有优点就很明显了,公用的代码都在一个类中,也就是父类中,统一修改比较方便,同时也最大化了代码的复用性。

使用场景一般就是:当要完成某个过程,该过程要执行一系列相关的步骤,这一系列的步骤基本相同。但只有个别步骤不相同的情况下,通常就考虑使用模板方法。

但要注意类爆炸的问题哟。

发布了152 篇原创文章 · 获赞 422 · 访问量 43万+

猜你喜欢

转载自blog.csdn.net/weixin_38111957/article/details/103418854