首页
登录 | 注册

封装不变,扩展可变——模版方法模式

1. 前言

在平时的项目开发中,我们常会碰到这样的需求。整个业务流程可以由若干操作完成,其中某些操作对所有客户都一样,是不变的,而有些操作确需要由客户端决定,是经常会改变的。比如事务操作,流程可以定义为:
1.开启事务
2.对数据库进行操作
3.成功则提交事务否则回滚
在这个事务操作流程中,1和3是不变的,而2需要由客户端决定,对数据库进行什么样的操作。又比如常见的jdbc操作,流程可以定义为:
1.获取数据库连接
2.通过连接操作数据库
3.释放连接
在这里,2和3是不变的,而1需要由客户端决定获取mysql还是oracle还是其他什么连接。
那么这么时候,我们就可以使用模版方法模式。

2. 模版方法模式详解

2.1 定义

模版方法模式在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模版方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。

2.2 类结构

封装不变,扩展可变——模版方法模式

2.3 使用场景

  • 当多个子类业务处理流程基本类似且只有某些处理步骤不一样时,可以将业务流程定义在父类的模版方法中,模版方法中可以包含实例方法和抽象方法,实例方法代表所有子类都一样的操作步骤,定义在父类中且由父类实现;抽象方法表示子类各不相同的处理步骤,父类定义但是由子类实现。
  • 重构代码的时候经常会用到,代码复用。

2.4 优点和缺点

  • 优点
    体现了“封装不变,扩展可变”的设计思想,符合开闭原则,有利于我们维护代码和对功能进行扩展。

  • 缺点
    行为由父类控制,但由子类实现,子类会影响父类结果,类层次结构复杂时会影响代码阅读。

2.5 简单实现

  • 抽象模版类
    该类有一个final修饰的模版方法,模版方法由三个方法组成,除了step2由自身实现外,step1和step3都由继承该类的子类实现
public abstract class AbstractClass {

    //步骤一,父类定义,子类实现
    protected abstract void step1();

    //步骤二,父类实现
    public void step2(){
        System.out.println("AbstractClass:step2");
    }

    //步骤三,父类定义,子类实现
    public abstract void step3();

    public final void templateMethod(){

        step1();
        step2();
        step3();

    }
}
  • 子类1
public class ConcreteClass1 extends AbstractClass {
    @Override
    protected void step1() {
        System.out.println("ConcreteClass1:step1");
    }

    @Override
    public void step3() {
        System.out.println("ConcreteClass1:step3");
    }
}
  • 子类2
public class ConcreteClass2 extends AbstractClass {
    @Override
    protected void step1() {
        System.out.println("ConcreteClass2:step1");
    }

    @Override
    public void step3() {

        System.out.println("ConcreteClass2:step3");
    }
}
  • 测试
public class TestCase {

    public static void main(String[] args) {

        AbstractClass c1=new ConcreteClass1();
        AbstractClass c2=new ConcreteClass2();
        c1.templateMethod();
        System.out.println("-------------------------------------");
        c2.templateMethod();
    }
}
  • 结果如下
    封装不变,扩展可变——模版方法模式

参考资料:

  • 《设计模式之禅》
  • 《head First 设计模式》

相关文章

  • 目录 引入 简单工厂 抽象工厂 Spring的bean工厂 模拟Spring工厂实现 模拟IOC 引入 假设有一个司机, 需要到某个城市, 于是我们给他一辆汽车 public class Demo { public static void ...
  • TensorFlow之DNN(三):神经网络的正则化方法(Dropout、L2正则化、早停和数据增强)
    这一篇博客整理用TensorFlow实现神经网络正则化的内容. 深层神经网络往往具有数十万乃至数百万的参数,可以进行非常复杂的特征变换,具有强大的学习能力,因此容易在训练集上过拟合.缓解神经网络的过拟合问题,一般有两种思路,一种是用正则化方 ...
  • WebGL three.js学习笔记 法向量网格材质MeshNormalMaterial的介绍和创建360度全景天空盒的方法
    WebGL学习----Three.js学习笔记(5) 点击查看demo演示 Demo地址:https://nsytsqdtn.github.io/demo/360/360 简单网格材质 MeshNormalMaterial MeshNorm ...
  • 补习系列(20)-大话 WebSocket 与 "尬聊"的实现
    目录 一.聊聊 WebSocket 二.Stomp 是个什么鬼 三.SpringBoot 整合 WebSocket A. 引入依赖 B. WebSocket 配置 C. 控制器 D. 前端实现 四.参考文档 一.聊聊 WebSocket 从 ...
  • 一.前言 在日常开发中,我们经常会碰到需要在运行时才知道对象个数的情况,这种情况不能使用数组,因为数组是固定数量的,这个时候我们就会使用集合,因为集合可以存储数量不确定的对象. 集合类是特别有用的工具类,不仅可以存储数量不等的对象,还可以实 ...
  • More Effective C++
    More Effective C++ 35个改善编程与设计的有效方法 只有深入了解C++编译器如何解释代码, 才有可能用C++语言写出健壮的软件. C++的难学, 不仅在其广博的语法, 语法背后的语义, 语义背后的深层思维, 深层思维背后的 ...

2020 cecdns.com webmaster#cecdns.com
12 q. 0.082 s.
京ICP备10005923号