设计模式—模板方法模式

简述

提取算法中不变的部分封装成方法,变化的部分延迟到子类

延迟到子类
这个说法在学习设计模式的时候经常出现,实际就是利用多态在子类中重写方法,使得实行时根据实例的类型调用不同的方法。

话不多说,看个案例。

优化案例

最初版v0

连接数据库我们有很多种方式,JDBC、JNDI、ODBC等等。下面是不使用设计模式模拟使用三种方式实现连接数据库。

public class Client {
    public static void main(String[] args) {
        JDBC jdbc = new JDBC();
        jdbc.execute(); // 使用jdbc连接数据库
        JNDI jndi = new JNDI();
        jndi.execute(); // 使用jndi连接数据库
        ODBC odbc = new ODBC();
        odbc.execute(); // 使用odbc连接数据库
    }
}

public class JDBC {
    public void execute() {
        System.out.println("读取数据库链接配置文件");
        System.out.println("使用JDBC建立数据库链接。。。");
        System.out.println("数据库链接成功");
    }
}

public class ODBC {
    public void execute() {
        System.out.println("读取数据库链接配置文件");
        System.out.println("使用ODBC建立数据库链接。。。");
        System.out.println("数据库链接成功");
    }
}

public class JNDI {
    public void execute() {
        System.out.println("读取数据库链接配置文件");
        System.out.println("使用JNDI建立数据库链接。。。");
        System.out.println("数据库链接成功");
    }
}

可以看出以上代码中有两处不变的代码 –> System.out.println("读取数据库链接配置文件")System.out.println("数据库链接成功")。这两处代码分别在三个类中重复了三次。案例中只有两行代码,问题不大,但是真实项目中可能会存在几百行代码完全相同但是到处都有的情况。为了解决这个问题,提高我们开发的效率,并且也能提高bug筛查的效率,我们可以使用模板方法模式。详细请看以下案例。

提高bug筛查的效率的原因
如果几百行的代码重复出现在十几个或者几十个不同的类中,当bug出现在一处代码时,为了确保系统不再出现同样的错误,需要把剩余所有相同的代码都检查一遍,这无疑增加了后期维护的成本。
而使用模板方法模式则可以省去很多花在这类杂活上的时间。

修改版v1

public class Client {
    public static void main(String[] args) {
        JDBC jdbc = new JDBC();
        jdbc.templateExecute(); // 使用jdbc连接数据库
        JNDI jndi = new JNDI();
        jndi.templateExecute(); // 使用jndi连接数据库
        ODBC odbc = new ODBC();
        odbc.templateExecute(); // 使用odbc连接数据库
    }
}

public abstract class DBConnection {
    // 模板方法
    public void templateExecute() {
        System.out.println("读取数据库链接配置文件"); // 不变的代码1
        this.execute();
        System.out.println("数据库链接成功"); // 不变的代码2
    }

    public abstract void execute();
}

public class JDBC extends DBConnection {
    public void execute() {
        System.out.println("使用JDBC建立数据库链接。。。");
    }
}

public class ODBC extends DBConnection {
    public void execute() {
        System.out.println("使用ODBC建立数据库链接。。。");
    }
}

public class JNDI extends DBConnection {
    public void execute() {
        System.out.println("使用JNDI建立数据库链接。。。");
    }
}

就增加一个抽象类和一个模板方法就解决了代码重复的问题。现在重复的代码就两行,所以效果不明显,如果是几百行,那效果立竿见影,而且模板方法模式也没有什么复杂的理念,简单易懂。悄悄告诉你,模板方法模式在各种框架中都是非常常见的。

总结

优点

  • 可以减少项目中大量重复代码。
  • 设计思想简单(就继承+多态),易懂。
  • 实现简单,只需要增加一个抽象类,增加一个模板方法即可。

缺点

  • 说实话,个人觉得没啥缺点。要是一个模板方法模式也能增加代码的阅读难度的话,还是转行比较好哈哈哈。

适用场景

  • 任何可以明确分清变化与不变化的代码。