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

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 设计模式》
posted @ 2018-07-05 14:55  takumiCX  阅读(409)  评论(0编辑  收藏  举报