zoukankan      html  css  js  c++  java
  • 封装不变,扩展可变——模版方法模式

    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 设计模式》
  • 相关阅读:
    linux根目录空间不足
    兴趣点 / 关键点( Interest point/Keypoint )
    opencv批量修改图片尺寸
    Excel批量修改文件
    xm数据写入
    opencv矩阵操作
    SVM参数解析
    Mat取行或列
    clone()与image和 cloneTo()
    最大连通域(指针)
  • 原文地址:https://www.cnblogs.com/takumicx/p/9268316.html
Copyright © 2011-2022 走看看