gof设计模式图解 (gof设计模式有多少种)

软件项目实训及课程设计指导——如何应用GOF设计模式中的构建者模式创建复合对象实例

1、GOF设计模式中的构建者模式

构建者设计模式能够将一个复杂对象(它一般为组合类)的构建过程与它的表示部件相互分离,使得同样的构建过程可以创建出不同的表示部件——也就是希望所获得的目标组合对象(一般为大对象)不依赖于组成它的各个部件子对象。

从而可以分离和解耦"过程"和"部件"——为了将构建复合对象的"过程"和它的"部件"解耦——也就是实现将"零部件生产"和复合对象的"生产过程"相互分离,使得某个"过程"能够应用于不同的"复合对象"的创建工作。

2、应用构建者设计模式的主要目的

构建者设计模式是满足面向对象OOP类设计中的"开放—封闭"设计原则的——由于一个复合对象是由各个部分的子对象所组成的,同时各个子对象部分又会经常变化,但组合在一起的算法(规则)却相对稳定。封装隔离这个复杂对象的各个变化的子对象部分,从而保持组合这些对象的算法的稳定性。

由于将各个零部件对象组合成为一个大的对象过程往往是很复杂的(比如汽车的总装配过程),为此可以将这些"零件"的组合过程"外部化"到一个称作创建者的对象中,创建者返还给客户端的是一个全部零件都建造完毕的最终产品对象。

3、构建者设计模式的程序代码实现示例

下面以创建JDBC数据库访问编程中的Statement语句对象实例为示例,为读者说明构建者设计模式的具体含义和详细的编程实现代码。为了方便读者阅读如下的程序代码示例,作者再附录出如下示例图。它为构建者设计模式的UML类图,从UML类图中可以了解到构建者设计模式在编程实现方面的核心要求是在指导者Director类中,内聚一个建造者对象。

gof设计模式有多少种,gof设计模式图解

(1)设计构建者接口StatementBuilder

在构建者接口中定义构建的基本过程和各个过程中所涉及的功能方法,请见下面的程序代码中的StatementBuilder接口代码示例——构建者接口StatementBuilder的代码示例。

package com.px1987.builderPattern;
import java.sql.*;
public interface StatementBuilder {
      public void loadJDBCDriverClass();
      public void connectionToDB();
      public void createStatement();
      public Statement getStatement();
}

该接口定义如何创建复杂对象的各个部件,应该在此接口中声明两种类型的方法:其一是建造各个部件的方法,另一个是返回复合对象(组装成品结果)的方法。

(2)针对MySQL数据库系统设计一个具体的构建者MySQLStatementBuilder

下面则是根据具体的应用环境分别构造出构建者接口StatementBuilder的不同实现类,在该实现类中实现创建各个具体部件的方法,并提供一个可以重新获取装配后的结果产品的具体实现。下面的程序代码中的代码代表针对MySQL数据库系统的一个具体的构建者MySQLStatementBuilder类的程序代码——构建者接口StatementBuilder的实现类的代码示例。

package com.px1987.builderPattern;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
public class MySQLStatementBuilder implements StatementBuilder {
      Connection con = null;
      Statement oneStatement=null;
      public MySQLStatementBuilder() {
      }
      public void loadJDBCDriverClass() {
          try {
          			Class.forName("com.mysql.jdbc.Driver");
          }
          catch (java.lang.ClassNotFoundException e) {
          			System.out.println("异常信息为:"+e.getMessage());
          }
      }
      public void connectionToDB() {
            try {
                con =
                DriverManager.getConnection("jdbc:mysql://localhost:3306/webbank","root","root");
            }
            catch (java.sql.SQLException e) {
           			 System.out.println("不能正确地连接数据库并且出现SQLException");
            }
      }
      public void createStatement() {
            try{
            			oneStatement=con.createStatement();
            }
            catch (java.sql.SQLException e) {
            			System.out.println("不能正确地创建Statement对象");
            }
      }
      public Statement getStatement(){
      			return oneStatement;
      }
}

(3)针对微软MS SQLServer2000数据库系统设计一个具体的构建者MSSQLServerStatementBuilder

下面的程序代码中的代码代表针对微软MS SQLServer2000数据库系统的一个具体的构建者MSSQLServerStatementBuilder类的程序代码——如下的程序代码为某个具体的构建者MSSQLServerStatementBuilder类的代码示例。

package com.px1987.builderPattern;
import java.sql.*;
public class MSSQLServerStatementBuilder implements StatementBuilder{
      Connection con = null;
      Statement oneStatement=null;
      public MSSQLServerStatementBuilder() {
      }
      public void loadJDBCDriverClass() {
          try {
          		Class.forName("net.sourceforge.jtds.jdbc.Driver");
          }
          catch (java.lang.ClassNotFoundException e) {
          		System.out.println("异常信息为:"+e.getMessage());
          }
      }
      public void connectionToDB() {
            try {
                  con =
                  DriverManager.getConnection("jdbc:jtds:sqlserver://127.0.0.1:1433/webbank",
                  "sa","1234");
            }
            catch (java.sql.SQLException e) {
            			System.out.println("不能正确地连接数据库并且出现SQLException");
            }
      }
      public void createStatement() {
            try{
           			 oneStatement=con.createStatement();
            }
            catch (java.sql.SQLException e) {
            			System.out.println("不能正确地创建Statement对象");
            }
      }
      public Statement getStatement(){
      			return oneStatement;
      }
}

(4)设计一个指导者StatementDirector类

构建者设计模式中的"指导者"有点类似于电影导演的角色,负责对最终的产品对象的总装配。用指导者StatementDirector类构建最后的复杂对象,并实现如何将部件最后组装成成品(参见其中的constructStatement()方法内的代码示例)。

请见下面的程序代码示例中的constructStatement方法代码——指导者StatementDirector类的代码示例。

package com.px1987.builderPattern;
public class StatementDirector {
      StatementBuilder oneStatementBuilder=null;
      public StatementDirector() {
      }
      public StatementDirector(StatementBuilder oneStatementBuilder){
      			this.oneStatementBuilder=oneStatementBuilder;
      }
      public void constructStatement(){
            //下面为创建出Statement对象的基本流程,该流程适应于各种数据库类型,但不同的数据库在三个部分中又有差别
            oneStatementBuilder.loadJDBCDriverClass();
            oneStatementBuilder.connectionToDB();
            oneStatementBuilder.createStatement();
      }
}

(5)设计一个创建构建者对象实例的StatementBuilderFactory类

通过该工厂类StatementBuilderFactory创建出不同的构建者对象实例以包装对它的创建过程和创建逻辑的细节,请见 下面的程序代码中的创建构建者对象实例的工厂类StatementBuilderFactory的代码示例——创建构建者对象实例的StatementBuilderFactory类的代码示例。

package com.px1987.builderPattern;
public class StatementBuilderFactory {
    public static final int MSSQLServerStatementBuilder=1;
    public static final int MySQLStatementBuilder=2;
    public static StatementBuilder newStatementBuilderInstance(int StatementBuilderKind){
          StatementBuilder oneStatementBuilder=null;
          switch(StatementBuilderKind){
              case 1:
              			oneStatementBuilder=new MSSQLServerStatementBuilder();
              break;
              case 2:
              			oneStatementBuilder=new MySQLStatementBuilder();
              break;
          }
          return oneStatementBuilder;
    }
}

提供该工厂类的主要目的是避免在客户端中涉及对具体的StatementBuilder接口的各个不同的实现类的具体耦合。如下为设计一个测试的功能类BuilderPatternTest 的代码示例。

package com.px1987.builderPattern;
import java.sql.*;
public class BuilderPatternTest {
      public BuilderPatternTest() {
      }
      public static void main(String[] args) {
          StatementBuilder oneStatementBuilder=
          StatementBuilderFactory.newStatementBuilderInstance(
          StatementBuilderFactory.MySQLStatementBuilder);
          StatementDirector oneStatementDirector=new StatementDirector(oneStatementBuilder);
          oneStatementDirector.constructStatement();
          Statement oneStatement=oneStatementBuilder.getStatement();
          if(oneStatement!=null) {
          			System.out.println("正确地构建出MySQL的JDBC Statement类的对象实例");
          }
          else{
          			System.out.println("没有构建出MySQL的JDBC Statement类的对象实例");
          }
          oneStatementBuilder=StatementBuilderFactory.newStatementBuilderInstance(
          StatementBuilderFactory.MSSQLServerStatementBuilder);
          oneStatementDirector=new StatementDirector(oneStatementBuilder);
          oneStatementDirector.constructStatement();
          oneStatement=oneStatementBuilder.getStatement();
          if(oneStatement!=null) {
          			System.out.println("正确地构建出SQLServer的Statement类的对象实例");
          }
          else{
          			System.out.println("没有构建出SQLServer的Statement类的对象实例");
          }
      }
}

(7)执行该测试功能BuilderPatternTest类的代码

在MyEclipse工具中直接以Java应用程序的方式执行该测试功能BuilderPatternTest类的代码,将出现如下图所示的结果。

gof设计模式有多少种,gof设计模式图解

通过该程序代码的实现示例,读者应该对构建者设计模式的特点——"客户只需要通过指定复杂对象的类型和内容来创建出该复杂的对象,而不必需要知道其创建的实现细节过程",有所体验!

软件项目实训及课程设计指导——如何对课程设计中的项目进行选型

如何合理地创建对象实例以降低程序类之间关系的耦合度

如何正确应用对象/关系映射技术实现系统持久层中各个DAO组件

深入理解面向对象OOP技术中各种程序类之间的相互关系(下篇)

深入理解面向对象OOP技术中各种程序类之间的相互关系(上篇)