• java设计模式——模板方法模式


    一. 定义与类型

    定义:定义了一个算法的骨架,并允许子类为一个或多个步骤提供实现,模板方法使得子类可以在不改变算法结构的情况下,重新定义算法的某些步骤

    类型:行为型。

    二. 使用场景

    (1) 一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现

    (2)  各子类中公共的行为被提取出来并集中到一个公共父类中,从而避免代码重复

    三. 优缺点

    优点:

      (1)  提高复用性,将相同部分的代码,放入抽象父类中

      (2)  提高扩展性

      (3)  符合开闭原则

    缺点:

      (1) 类数目增加

      (2) 增加了系统实现的复杂度

      (3) 继承关系自身缺点,如果父类添加新的抽象方法,所有子类都要改一遍

    四. 模板方法—扩展

    钩子方法

    五. 相关设计模式

    模板方法模式和工厂方法模式

      工厂方法是模板方法的一种特殊实现

    模板方法模式和策略模式

      它们都有封装算法,策略模式的目的是使不同的算法可以相互替换,并且不影响应用层客户端的使用;而模板方法模式是针对一个定义算法的流程而将一些不太一样的,具体实现步骤交给子类来实现。模板方法是不改变算法的流程,而策略模式是可以改变的,有大量的if-else时,就可以考虑是否使用策略模式

    六. Coding

    模板方法模式其实非常简单,直接看下面的代码

    /**
     * @program: designModel
     * @description:
     * @author: YuKai Fan
     * @create: 2019-02-13 14:50
     **/
    public abstract class ACourse {
        //不希望子类覆盖这个方法,防止修改方法里面的录制课程流程的执行顺序
        protected final void makeCourse() {
            this.makePPT();
            this.makeVide0();
            if (needWriteArticle()) {
                this.writeArticle();
            }
            this.packageCourse();
        }
    
        final void makePPT() {
            System.out.println("制作PPT");
        }
    
        final void makeVide0() {
            System.out.println("制作视频");
        }
    
        final void writeArticle() {
            System.out.println("编写手记");
        }
    
        //钩子方法
        protected boolean needWriteArticle() {
            return false;
        }
    
        abstract void packageCourse();
    }
    /**
     * @program: designModel
     * @description:
     * @author: YuKai Fan
     * @create: 2019-02-13 14:55
     **/
    public class DesignPatternCourse extends ACourse {
        void packageCourse() {
            System.out.println("提供课程java源代码");
        }
    
        @Override
        protected boolean needWriteArticle() {
            return true;
        }
    }
    /**
     * @program: designModel
     * @description:
     * @author: YuKai Fan
     * @create: 2019-02-13 14:56
     **/
    public class FECourse extends ACourse {
        private boolean needWriteArticleFlag = false;
        void packageCourse() {
            System.out.println("提供课程的前端代码");
            System.out.println("提供课程的图片等多媒体素材等");
        }
    
        //这样的写法是为了满足不同的前端课程,可能jquery需要写手记,而html/css不需要写
        public FECourse(boolean needWriteArticleFlag) {
            this.needWriteArticleFlag = needWriteArticleFlag;
        }
    
        @Override
        protected boolean needWriteArticle() {
            return this.needWriteArticleFlag;
        }
    }
    /**
     * @program: designModel
     * @description:
     * @author: YuKai Fan
     * @create: 2019-02-13 14:57
     **/
    public class Test {
        public static void main(String[] args) {
            System.out.println("后端设计模式课程start---");
            ACourse designPatternCourse = new DesignPatternCourse();
            //这里涉及到的钩子方法,其实是子类重写父类方法的一些基础规则,子类调用父类的方法,如果是被重写的,那调用的其实是子类重写过后的方法
            //也就是说,子类重写了父类的needWriteArticle()方法,在调用父类的makeCourse()时,调用了needWriteArticle()其实是子类重写的方法,也就是返回了true
            designPatternCourse.makeCourse();
            System.out.println("后端设计模式课程end---");
    
            System.out.println("前端课程start---");
            ACourse feCourse = new FECourse(false);
            feCourse.makeCourse();
            System.out.println("前端课程end---");
    
        }
    }

    具体的步骤注释都已经写在了代码中。

    七. 源码分析

    JDK中AbstractList,AbstractSet,AbstractMap类使用了模板方法模式

    Servlet中的HttpServlet,doGet,doPost,service方法都是使用了模板方法

    Mybatis中的BaseExecutor类也是采用了模板方法

  • 相关阅读:
    一个类GraphQL的ORM数据访问框架发布
    关于 IIS Express 常用设置
    代码失控与状态机(上)
    实体类的动态生成(三)
    实体类的动态生成(二)
    搭建 github.io 博客站点
    实体类的动态生成(一)
    JDK的下载和安装
    三步搞定jupyter nootebook 主题切换
    LeetCode刷题--存在重复元素
  • 原文地址:https://www.cnblogs.com/FanJava/p/10370096.html
Copyright © 2020-2023  润新知