课程名称:程序设计方法学
实验3:面向对象程序设计(一)—— 创建型模式
时间:2015年11月 4日星期三,第3、4节
一、实验目的
1. 理解面向对象的设计模式;
2. 理解创建型模式。
二、实验内容
某软件开发公司要开发一套通用的企业信息管理系统,用于访问客户企业内部的关系数据库,为客户处理并生成相关的决策信息。由于该系统面对的潜在客户自身的规模及应用需求不同,该系统最终在实际生产环境中使用的后台数据库产品可能是Microsoft SQL Server, IBM DB2或Oracle,而且将来还可能扩展到其它的数据库产品。为此,急需为该系统设计并开发一个通用的数据访问层,以便使系统在安装部署时能够简单的在不同的数据库产品中进行切换。
经研究分析,系统分析师为数据访问层抽象出了三类对象,分别是DBConnection(即数据连接对象,用于建立到数据库的物理连接,并实现事务管理等功能)、DBQuery(数据查询对象,用于传递SQL查询语句到数据库,并从数据库返回查询的结果)、DBUpdater(数据更新对象,用于对数据库执行增、删、改等命令)。
请你选择适当的面向对象设计模式,使用面向对象的建模方法,给出该数据访问层的设计,使其在满足基本需求的前提下具有最佳的可扩展性。
要求:
实验报告中要求绘制UML类图,给出设计中各个类的主要成员,并附以适当的文字说明详细描述每个类的作用;
实验报告中应针对上述设计,给出使用C++(或java)实现的完整的示意性代码,以及在本地计算机上调试、运行该程序的截图(要求截图的结果中能体现个人的学号、姓名等信息)。
实验报告的末尾请对所用的设计模式、该模式的优缺点及使用心得等做简要小结。
三、实验环境
硬件条件:微机
操作系统:Windows 2007
开发环境:Eclipse,Rational Rose 2003
四、实验步骤和结果
(一)选择适当的面向对象设计模式
由题意,在企业信息管理系统中,实际生产环境中使用的数据产品有三类,它们分别是:Microsoft SQL Server, IBM DB2和Oracle,并且每次只会使用其中一个产品,而且将来还可能扩展到其它的数据库产品,所以要考虑到产品的可扩展性和可维护性。而对于每个数据库产品可抽象出三类对象,分别是:DBConnection(即数据连接对象,用于建立到数据库的物理连接,并实现事务管理等功能)、DBQuery(数据查询对象,用于传递SQL查询语句到数据库,并从数据库返回查询的结果)、DBUpdater(数据更新对象,用于对数据库执行增、删、改等命令)。每个人数据库产品都需要这三类对象。所以此题选择的是“抽象工厂模式”。
该抽象工厂模式有如下几个部分:
抽象工厂:用于生产三类数据产品的接口或抽象类。
具体工厂:具体各类数据库产品的创建者,含有具体的业务逻辑有关的代码。
抽象产品:具体的数据库产品的三类对象的抽象。
具体产品:创建具体工厂的具体对象。
(二)UML类图的设计和绘制
(图1 抽象工厂模式构造图)
(图2 UML 总类图)
(图3 DBFactory 抽象工厂类图)
(图4 DBConnection 抽象产品类图)
(图5 DBQuery 抽象产品类图)
(图6 DBUpdater 抽象产品类图)
DBFactory类的作用:DBFactory是抽象工厂,是具体工厂的父类,在示例代码中用接口实现接口。
DBConnection类的作用:DBConnection是抽象产品,具体的产品继承或者实现该接口。
DBQuery类的作用:DBQuery是抽象产品,具体的产品继承或者实现该接口。
DBUpdater类的作用:DBUpdater是抽象产品,具体的产品继承或者实现该接口。
(三)针对上述设计,用java实现的完整的示意性代码如下所示:
- 抽象工厂
package Factory; public interface DBFactory { public DBQuery CreateDBQuery(); public DBConnection CreateDBConnection(); public DBUpdater CreateDBUpdater(); }
2.具体工厂
(1)SQLServer数据库
//具体工厂:SQLServer数据库 package Factory; public class SQLServerFactory implements DBFactory{ public SQLServerFactory() { super(); System.out.println("**********沈_10503**********"); System.out.println("【现在开始使用SQLServer数据库】"); } public DBQuery CreateDBQuery() { // TODO Auto-generated method stub return new DBQuerySQLServer(); } public DBConnection CreateDBConnection() { // TODO Auto-generated method stub return new DBConnectionSQLServer(); } public DBUpdater CreateDBUpdater() { // TODO Auto-generated method stub return new DBUpdaterSQLServer(); } }
(2)IBM DB2数据库
//具体工厂:IBM_DB2数据库 package Factory; public class IBM_DB2Factory implements DBFactory { public IBM_DB2Factory() { super(); System.out.println("**********沈_10503**********"); System.out.println("【现在开始使用IBM_DB2数据库】"); } public DBQuery CreateDBQuery() { // TODO Auto-generated method stub return new DBQueryIBM(); } public DBConnection CreateDBConnection() { // TODO Auto-generated method stub return new DBConnectionIBM(); } public DBUpdater CreateDBUpdater() { // TODO Auto-generated method stub return new DBUpdaterIBM(); } }
(3)Oracle数据库
//具体工厂:Oracle数据库 package Factory; public class OracleFactory implements DBFactory { public OracleFactory() { super(); System.out.println("**********沈_10503**********"); System.out.println("【现在开始使用Oracle数据库】"); } public DBQuery CreateDBQuery() { // TODO Auto-generated method stub return new DBQueryOracle(); } public DBConnection CreateDBConnection() { // TODO Auto-generated method stub return new DBConnectionOracle(); } public DBUpdater CreateDBUpdater() { // TODO Auto-generated method stub return new DBUpdaterOracle(); } }
3.抽象产品
(1)DBConnection
package Factory; public interface DBConnection { public void Connection(); }
(2)DBQuery
package Factory; public interface DBQuery { public void Query(); }
(3)DBUpdater
package Factory; public interface DBUpdater { public void Add(); public void Delete(); public void Alter(); }
4.具体产品
(1)DBConnectionSQLServer
package Factory; public class DBConnectionSQLServer implements DBConnection { public DBConnectionSQLServer() { super(); System.out.println("您正在使用SQLServer连接功能"); } public void Connection() { System.out.println(">>>>SQLServer正在进行数据连接..."); } }
(2)DBConnectionIBM
package Factory; public class DBConnectionIBM implements DBConnection{ public DBConnectionIBM() { super(); System.out.println("您正在使用IBM_DB2连接功能"); } public void Connection() { System.out.println(">>>>IBM_DB2 正在进行数据连接..." ); } }
(3)DBConnectionOracle
package Factory; public class DBConnectionOracle implements DBConnection{ public DBConnectionOracle() { super(); System.out.println("您正在使用Oracle数据库连接功能"); } public void Connection() { System.out.println(">>>>Oracle 正在进行数据连接..."); } }
(4) DBQuerySQLServer
package Factory; public class DBQuerySQLServer implements DBQuery { public DBQuerySQLServer() { super(); System.out.println("您正在使用SQLServer数据查询功能!"); } public void Query() { System.out.println(">>>> SQLServer正在数据查询..."); } }
(5)DBQueryIBM
package Factory; public class DBQueryIBM implements DBQuery{ public DBQueryIBM() { super(); System.out.println("您正在使用IBM_DB2数据查询"); } public void Query() { System.out.println(">>>>IBM_DB2正在数据查询..."); } }
(6)DBQueryOracle
package Factory; public class DBQueryOracle implements DBQuery{ public DBQueryOracle() { super(); System.out.println("您正在使用 Oracle数据查询"); } public void Query() { System.out.println(">>>>Oracle 正在查询数据..."); }}
(7)DBUpdaterSQLServer
package Factory; public class DBUpdaterSQLServer implements DBUpdater{ public DBUpdaterSQLServer() { super(); System.out.println("您正在使用SQLServer数据更新功能!"); } public void Add() { System.out.println(">>>>SQLServer 增添数据..."); } public void Delete() { System.out.println(">>>>SQLServer 删除数据..."); } public void Alter() { System.out.println(">>>>SQLServer 修改数据..."); } }
(8)DBUpdaterIBM
package Factory; public class DBUpdaterIBM implements DBUpdater{ public DBUpdaterIBM() { super(); System.out.println("您正在使用IBM_DB2数据更新功能!"); } public void Add() { System.out.println(">>>>IBM_DB2 增添数据..." ); } public void Delete() { System.out.println(">>>>IBM_DB2 删除数据 ..." ); } public void Alter() { System.out.println(">>>>IBM_DB2 修改数据 ..." ); } }
(9)DBUpdaterOracle
package Factory; public class DBUpdaterOracle implements DBUpdater { public DBUpdaterOracle() { super(); System.out.println("您正在使用Oracle 数据更新功能!"); } public void Add() { System.out.println(">>>>Oracle 增添数据..."); } public void Delete() { System.out.println(">>>>Oracle 删除数据..."); } public void Alter() { System.out.println(">>>>Oracle 修改数据..."); } }
(四)编写测试代码如下所示:
package Factory; public class Main { /** * @param arg*/ public static void main(String[] args) { //创建一个SQLServer数据库产品 SQLServerFactory sqlServerFactory=new SQLServerFactory(); //使用DBConnection功能 DBConnectionSQLServer dbConnectionSQLServer=new DBConnectionSQLServer(); dbConnectionSQLServer.Connection(); //使用DBQuery功能 DBQuerySQLServer dbQuerySQLServer=new DBQuerySQLServer(); dbQuerySQLServer.Query(); //使用DBUpdater功能 DBUpdaterSQLServer dbUpdaterSQLServer=new DBUpdaterSQLServer(); dbUpdaterSQLServer.Add(); dbUpdaterSQLServer.Delete(); dbUpdaterSQLServer.Alter(); //创建一个IBM_DB2数据库产品 IBM_DB2Factory ibm_DB2Factory=new IBM_DB2Factory(); //使用DBConnection功能 DBConnectionIBM dbConnectionIBM=new DBConnectionIBM(); dbConnectionIBM.Connection(); //使用DBQuery功能 DBQueryIBM dbQueryIBM=new DBQueryIBM(); dbQueryIBM.Query(); //使用DBUpdater功能 DBUpdaterIBM dbUpdaterIBM=new DBUpdaterIBM(); dbUpdaterIBM.Add(); dbUpdaterIBM.Delete(); dbUpdaterIBM.Alter(); //创建一个Oracle数据库产品 OracleFactory oracleFactory=new OracleFactory(); //使用DBConnection功能 DBConnectionOracle dbConnectionOracle=new DBConnectionOracle(); dbConnectionOracle.Connection(); //使用DBQuery功能 DBQueryOracle dbQueryOracle=new DBQueryOracle(); dbQueryOracle.Query(); //使用DBUpdater功能 DBUpdaterOracle dbUpdaterOracle=new DBUpdaterOracle(); dbUpdaterOracle.Add(); dbUpdaterOracle.Delete(); dbUpdaterOracle.Alter(); } }
调试程序,运行结果如图所示:
五、实验结果和讨论
在编写完相应代码及测试程序后,调试程序,运行结果如图所示:
六、总结
(一)本次实验按时按量完成。通过实验基本掌握了创建型模式的抽象工厂模式。
(二)本次实验使用的是抽象工厂模式,它只需提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
优点: 抽象工厂模式隔离了具体类的生成,使客户不需要知道什么被创建。易于交换产品系列,只需改变具体的工厂就可以使用不同的产品配置。有利于产品的一致性,一个系列中 的产品对象被设计成一起工作。当一产品族中的多个对象被设计成一起工作时,它可保证客户段始终只使用同一个产品族中的对象。增加新的具体工厂和产品族很方便,无需修改已 有的系统,符合开闭原则。
缺点: 难以支持新的产品等级结构,支持新的产品等级结构就要扩展抽象工厂接口。
(三)工厂方法模式针对的是一个产品等级结构;而抽象工厂模式针对的是多个产品等级结构。在抽象工厂模式中,产品族是指由同一个工厂生产的,位于不同产品等级结构中的一组产品。比如DBConnection,DBQuery,DBUpdater这三个为3个产品族。
(四)使用抽象工厂模式的心得体会:
抽象工厂模式的用意为:给客户端提供一个接口,可以创建多个产品族中的产品对象。而且使用抽象工厂模式还要满足一下条件:
1.系统中有多个产品族,而系统一次只可能消费其中一族产品。
2.同属于同一个产品族的产品以其使用。
以下是抽象工厂模式的各个角色:
1.抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。
2.具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。在java中它由具体的类来实现。
3.抽象产品角色:它是具体产品继承的父类或者是实现的接口。在java中一般有抽象类或者接口来实现。
4.具体产品角色:具体工厂角色所创建的对象就是此角色的实例。在java中由具体的类来实现。
抽象工厂模式可以看成是工厂方法模式的一种推广,而工厂方法模式是一种极端情况的抽象工厂模式,其实工厂方法模式是用来创建一个产品的等级结构的,而抽象工厂模式是用来创建多个产品的等级结构的。工厂方法创建一般只有一个方法,创建一种产品。抽象工厂一般有多个方法,创建一系列产品。工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。
对于工厂方法模式:
一个抽象产品类,可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类只能创建一个具体产品类的实例。
对于抽象工厂模式:
多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类可以创建多个具体产品类的实例。