zoukankan      html  css  js  c++  java
  • 透过简单例子说明“工厂方法模式”与“模板方法模式”

      最近看了一下阎宏博士的《java与模式》,看的不多,的确很经典,通俗易懂,工作中很多的问题一下子就明朗了(本人菜鸟……)。

      今天看到"工厂方法模式"(Factory Method)的一道思考题,其中又简单涉及了"模板方法模式"(Template Method),原来工作中不懂的地方就是用的这样的开发模式。书中的例子比较简单,很容易理解,所以就敲了一下代码,理解了一下。

      题目的大意是:

      现有两个数据库,假设是Mysql与Oracle两个数据库,要在Client客户端上分别能查出两个不同的数据库的结果,通过工厂方法模式,设计一个合理的方案。

      关于什么是工厂方法模式,书中给出的定义是:

      工厂方法模式是类的创建模式,又叫做虚拟构造子模式或者多态性工厂模式。工厂方法模式的用意是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类中。

      首先贴出他们之间关系的类图:

      

      

      代码部分如下:

      AbstractQueryRunner.java

     1 import java.sql.Connection;
     2 import java.sql.ResultSet;
     3 
     4 public abstract class AbstractQueryRunner {
     5     
     6     public ResultSet getResult(){
     7         Connection con = createConnection();
     8         String sql = createQueryString();
     9         return runSql(con,sql);
    10     }
    11     
    12     protected abstract Connection createConnection();
    13     protected abstract String createQueryString();
    14     protected abstract ResultSet runSql(Connection con,String sql);
    15 }

      

      AbstractQueryRunner的两个子类,即操作两个数据库的类:

      MysqlRunner.java

      

     1 import java.sql.Connection;
     2 import java.sql.ResultSet;
     3 import java.sql.SQLException;
     4 import java.sql.Statement;
     5 
     6 public class MysqlRunner extends AbstractQueryRunner {
     7 
     8     protected Connection createConnection(){
     9         //code here
    10         return con;
    11     }
    12     
    13     @Override
    14     protected String createQueryString() {
    15         String queryString = "SELECT * FROM User";
    16         return queryString;
    17     }
    18 
    19     protected ResultSet runSql(Connection con,String sql){
    20         try {
    21             Statement smt = con.createStatement();
    22             return smt.executeQuery(sql);
    23         } catch (SQLException e) {
    24             e.printStackTrace();
    25             return null;
    26         }
    27     }
    28 }

      OracleRunner.java

      

     1 import java.sql.Connection;
     2 import java.sql.ResultSet;
     3 import java.sql.SQLException;
     4 import java.sql.Statement;
     5 
     6 public class OracleRunner extends AbstractQueryRunner {
     7 
     8     protected Connection createConnection(){
     9         //code here
    10         return con;
    11     }
    12     
    13     @Override
    14     protected String createQueryString() {
    15         String queryString = "SELECT * FROM User";
    16         return queryString;
    17     }
    18 
    19     protected ResultSet runSql(Connection con,String sql){
    20         try {
    21             Statement smt = con.createStatement();
    22             return smt.executeQuery(sql);
    23         } catch (SQLException e) {
    24             e.printStackTrace();
    25             return null;
    26         }
    27     }
    28 }

    可以看到,两个子类重写了父类没有具体实现的方法,这样做的好处是子类可以任意写自己内部的方法,是一种"开-闭原则"的体现。

      客户端代码:

      Client.java

      

     1 import java.sql.ResultSet;
     2 public class Client {
     3 
     4     public static void main(String[] args) {
     5         AbstractQueryRunner mRunner = new MysqlRunner();
     6         ResultSet result1 = mRunner.getResult();
     7         
     8         AbstractQueryRunner oRunner = new OracleRunner();
     9         ResultSet result2 = oRunner.getResult();
    10     }
    11     
    12 }


    这样就能实现使用工厂方法模式在客户端查询不同的数据库了。

    总体使用了工厂方法模式,那模板方法模式体现在哪里呢,它就是其中的getResult()方法。关于模板方法模式的解释,我翻阅了一下该书,它其中解释的很详细,现摘录如下:

      模板方法模式是类的行为模式。准备一个抽象类,将部分逻辑以具体方法以及具体构造子的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑。不同的构造子类可以以不同的方法实现这些抽象方法,从而对剩余的逻辑有不同的实现。这就是模板方法模式的用意。

      

  • 相关阅读:
    Linux:Day16(下)
    Linux:Day17(上) gawk基础
    Linux:Day16(上)
    Linux:Day15(下)
    Linux:Day15(上)
    (蓝桥杯直播)递归原理与构造技巧
    Java命名规范
    String、String.valueOf、toString 它们三者的区别总结
    Java StringBuffer 和 StringBuilder 类
    java中,为什么char类型数组可以直接用数组名打印,打印结果居然不是地址值!
  • 原文地址:https://www.cnblogs.com/bigbang92/p/3478262.html
Copyright © 2011-2022 走看看