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

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

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

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

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

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

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

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

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

(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类的代码,将出现如下图所示的结果。

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

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

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

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

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

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

sql中如何统计各种零件的总数量_如何应用GOF设计模式中的构建者模式创建复合对象实例...相关推荐

  1. sql中如何统计各种零件的总数量_[Python]提取数据库中数据, 用人货场的分析方法, 对电商双十一促销活动结果数据进行复盘分析...

    背景 某电商公司最近举行了一场促销活动,该案例是对此次活动的一次复盘和分析.所需要用到的工具有Python + SQL. python会用到的库有: sqlalchemy pandas sklearn ...

  2. sql中如何统计各种零件的总数量_数据蒋堂 | SQL是描述性语言?

    作者:蒋步星 来源:数据蒋堂 本文共1200字,建议阅读8分钟.用SQL写代码时一般不用再关心变量.循环的具体动作,但要操心表.字段这些概念上的计算过程. 我们在学习SQL时,常常会看到这样的论调:S ...

  3. 《Autosar从入门到精通-实战篇》总目录_培训教程持续更新中...

    目录 一.Autosar入门篇: 1.1 DBC专题(共9篇) 1.2 ARXML专题(共35篇) 1.2.1 CAN Matrix Arxml(共28篇) 1.2.2 ASWC Arxml(共7篇) ...

  4. 《Autosar_BSW高阶配置》总目录_培训教程持续更新中...

    目录 0 基础"开胃菜"(共20+篇) 0.1 CANFD和Classic CAN介绍 0.2 UDS/OBD诊断网络层/传输层介绍 0.3 常用UDS诊断服务介绍 0.4 所有O ...

  5. 《Autosar_MCAL高阶配置》总目录_培训教程持续更新中...

    欢迎大家订阅<Autosar_MCAL高阶配置>专栏(可以理解为是Autosar培训教程),献上常用的案例和配置方法.下方整理了相关博文的链接(单击蓝色字体即可跳转),方便大家获取. 本专 ...

  6. iOS-查询数据库--指定数据表中的当前数据行的总数量

    很多时候,我们在查询一个表的时候,不想得到里面的记录内容,只是想简单的得到符合查询条件的记录条数. FMDB中有一个很简单的方法就可以实现,见下面的代码实例: #import "FMdata ...

  7. MySQL数据库中查询数据库表、字段总数量,查询数据总量

    最近要查询一些数据库的基本情况,由于以前用oracle数据库比较多,现在换了MySQL数据库,就整理了一部分语句记录下来. 1.查询数据库表数量 #查询MySQL服务中数据库表数据量SELECT CO ...

  8. 中查询一个文件夹下文件数量_如何在 Bash 中使用循环 | Linux 中国

    使用循环和查找命令批量自动对多个文件进行一系列的操作.-- Seth Kenlon(作者) 人们希望学习批处理命令的一个普遍原因是要得到批处理强大的功能.如果你希望批量的对文件执行一些指令,构造一个可 ...

  9. 代码中如何让无序标记的内容并排_英语技术文档中如何正确使用无序列表和有序列表?...

    Foreword 之前跟大家分享过英语技术文档中如何正确使用时态和英语技术文档中如何正确使用人称,这一篇再跟大家分享一下如何正确使用无序列表和有序列表. 其实,在技术文档中,除了无序列表和有序列表,另 ...

最新文章

  1. 扩增子图表解读1箱线图:Alpha多样性,老板再也不操心的我文献阅读了
  2. html h 不换行,css 强制不换行
  3. Linux 命令行敲命令 光标移动快捷键
  4. java伪协议_JavaScript中伪协议 javascript:使用探讨
  5. Effective 笔记
  6. 蒙昧的意思_蒙昧的意思
  7. Bash数组变量的赋值
  8. POI 方式-excle 表格导出实现-java-poi
  9. ARMA模型性质之平稳AR模型得统计性质
  10. PHP笔记-自定义MVC框架
  11. redis入门——服务器篇
  12. java学习第一课----java中8种基本类型
  13. python面试资格确认_Python面试必须要看的15个问题
  14. Java开发者值得关注的十个技术博客
  15. windows网络编程 gethostbyname()
  16. SpringBoot用HttpClient调用快递物流查询API接口
  17. 计算机组装工具以及装机流程,如何组装电脑,图文教程详解电脑组装全过程
  18. 异数OS-织梦师-PBFT(六) 走出区块链,加速破解PBFT
  19. 上海泛微面经(从Java开发到项目实施岗)
  20. UltraEdit 应用程序发生错误0xc0000417

热门文章

  1. 关于ELMo,面试官们都怎么问
  2. Transformers中的位置编码到底是什么?
  3. 学习C#以及C还有数据库
  4. Java 面向对象 之 引用传递
  5. nginx httpgzip模块
  6. 数据结构导论初步理解
  7. Javaweb中利用kaptcha生成验证码
  8. oracle表空间和用户的创建、修改、授权、查看等执行SQL
  9. SQL Server 中如何判断表是否存在
  10. 王者服务器维护宝箱礼包都没领,王者荣耀:S19战令最后一天,还没领取奖励的玩家要注意了...