设计模式之模版方法

往期文章

  • springcloud整合knike4j聚合微服务接口文档
  • spring源码 - 条件注解@ConditionnalOnClass的原理分析
  • springboot项目实现导出pdf功能,这也太简单了吧

    文章目录

    • 往期文章
    • 一、介绍
    • 二、入门示例
    • 三、实践
    • 四、使用场景
    • 五、总结

一、介绍

模版方法是23种设计模式中的一个,属于行为性设计模式。是对算法行为方式的一类设计。

所谓模版方法,就是在一个方法中,定义了一系列其他方法的调用顺序,而其他方法由各个子类实现。因此当调用这个方法时,它只提供了其他方法的调用顺序,其他方法的实现细节由调用方的实际类型决定。

简单理解就是定义一个模版,模版内的不同模块该如何实现交给子类完成。

打个比方,你是两个孩子(孩子A和孩子B)的爸爸,你给他们提出了一日三餐的规定,先吃早饭,再吃午饭,最后吃晚饭。

两个孩子很乖

  • 孩子A早饭喝粥,午饭吃饭,晚饭吃屎
  • 孩子B早饭吃包子,午饭吃面,晚饭喝尿

他们爱吃什么吃什么,这是他们的吃饭自由,反正实现了一日三餐的规定。

二、入门示例

下面我们用代码来描述模版方法的思想。

父类A定义了一个模版方法:一日三餐,以及另外三个方法:早饭、午饭、晚饭。其子类B和C分别对这三个方法进行重写来实现各自的逻辑。当这两个子类的对象调用继承自父类A的一日三餐时,就会按顺序对早饭、午饭、晚饭三个方法进行调用。代码如下

  • 定义一日三餐模版的父亲类

    public class Parent {
        // 一日三餐的模版
        public void threeMealsDaily() {
            // 早饭
            breakfast();
            // 午饭
            lunch();
            // 晚饭
            dinner();
        }
        // 早饭
        public void breakfast() {
        }
        // 午饭
        public void lunch() {
        }
        // 晚饭
        public void dinner() {
        }
    }
    
  • 儿子

    public class Son extends Parent{
        // 早饭
        @Override
        public void breakfast() {
            System.out.println("早饭:喝粥");
        }
        // 午饭
        @Override
        public void lunch() {
            System.out.println("午饭:米饭");
        }
        // 晚饭
        @Override
        public void dinner() {
            System.out.println("晚饭:吃屎");
        }
    }
    
  • 女儿

    public class Daughter extends Parent{
        // 早饭
        @Override
        public void breakfast() {
            System.out.println("早饭:包子");
        }
        // 午饭
        @Override
        public void lunch() {
            System.out.println("午饭:炒面");
        }
        // 晚饭
        @Override
        public void dinner() {
            System.out.println("晚饭:喝尿");
        }
    }
    
  • 测试

    public class TemplateDemo {
        
        public static void main(String[] args) {
            // 儿子的一日三餐
            Son son = new Son();
            System.out.println("==============儿子的一日三餐==============");
            son.threeMealsDaily();
    
            // 女儿的一日三餐
            Daughter daughter = new Daughter();
            System.out.println("==============女儿的一日三餐==============");
            daughter.threeMealsDaily();
        }
    }
    
  • 输出

    设计模式之模版方法_第1张图片

三、实践

在java中我们提倡面向接口编程,因此需要定义一个接口,来定义其实现类中的行为。另外需要将父类设置为抽象类并定义模版方法。因此在模版方法中存在这三个组件:

  • 接口类:定义模版方法
  • 抽象类:实现接口定义的模版方法,并定义抽象方法由子类实现
  • 具体实现类:继承抽象类,并实现抽象类定义的抽象方法

下面我们对上面的入门示例进行改造

  • 接口类:定义模版方法

    public interface Daily {
    
        // 日常活动
        void threeMealsDaily();
    }
    
  • 抽象类:实现接口定义的模版方法,并定义抽象方法由子类实现

    模版方法threeMealsDaily()设置为public是为了在任何地方都可以调用该方法

    实现细节设置为protected是为了控制其具体实现类的位置

    public abstract class Parent implements Daily {
        // 一日三餐的模版
        public void threeMealsDaily() {
            // 早饭
            breakfast();
            // 午饭
            lunch();
            // 晚饭
            dinner();
        }
        // 早饭
        protected abstract void breakfast();
        // 午饭
        protected abstract void lunch();
        // 晚饭
        protected abstract void dinner();
    }
    
  • 具体实现类:继承抽象类,并实现抽象类定义的抽象方法

    public class Daughter extends Parent {
        // 早饭
        @Override
        public void breakfast() {
            System.out.println("早饭:包子");
        }
        // 午饭
        @Override
        public void lunch() {
            System.out.println("午饭:炒面");
        }
        // 晚饭
        @Override
        public void dinner() {
            System.out.println("晚饭:喝尿");
        }
    }
    
    
    public class Son extends Parent {
        // 早饭
        @Override
        public void breakfast() {
            System.out.println("早饭:喝粥");
        }
        // 午饭
        @Override
        public void lunch() {
            System.out.println("午饭:米饭");
        }
        // 晚饭
        @Override
        public void dinner() {
            System.out.println("晚饭:吃屎");
        }
    }
    
  • 测试

    public class TemplateDemo {
    
        public static void main(String[] args) {
            // 儿子的一日三餐
            Daily son = new Son();
            System.out.println("==============儿子的一日三餐==============");
            son.threeMealsDaily();
    
            // 女儿的一日三餐
            Daily daughter = new Daughter();
            System.out.println("==============女儿的一日三餐==============");
            daughter.threeMealsDaily();
        }
    }
    
  • 输出

    设计模式之模版方法_第2张图片

四、使用场景

  • 在java集合中,LinkedHashMap与其父类HashMap以及抽象父类AbstractMap就是模版方法设计模式的体现
  • 在spring中,DispatcherServlet与其父类爷类祖爷类也是模版方法设计模式的复杂体现

五、总结

模版方法是比较简单的一种设计模式。但他还是有一些优缺点。

优点:通过模版定义方法,提高了代码的复用性的同时也提高了子类的个性化实现

缺点:当然是java单继承的缺陷了。



纸上得来终觉浅,绝知此事要躬行。

————我是万万岁,我们下期再见————

你可能感兴趣的:(设计模式,JAVA,设计模式,java)