最近有很多朋友跟我聊到关于“在软件项目开发中如何合理使用设计模式”的问题,希望我能够给出一些相对比较完整的真实项目实例,为了满足大家的要求,在后续文章中,我将拿出几个较为复杂的实例与大家一起分享,有些项目是我参与开发的,有些项目是在我的指导下开发的,希望能给大家带来帮助!在此我也希望大家能够分享自己的一些设计模式使用心得和好的设计模式应用实例,可以整理一份给我(可发送到邮箱:weiliu_china@126.com),在下一本设计模式图书(有计划明年写一本《设计模式案例剖析》,暂定名)中我将选取部分实例加入其中,如有入选者,Sunny承诺送签名图书两本,选择范围包括已经出版的《设计模式》、《设计模式实训教程》、《设计模式的艺术》,还包括马上要出版的《C#设计模式》和正在编写的《UML建模实训教程》,任君挑选,正版保证,假一罚十!
从本文开始,我将介绍一个数据库同步系统的设计方案,该系统是我在2010年给某软件公司做设计模式内训时指导几位开发人员所开发的一个项目,系统以某省级移动公司应急管理系统数据备份(数据库同步)需求为原型,基本需求如下:
为了在数据库发生故障的情况下不影响核心业务的运行,需要将生产数据库定期备份到应急数据库,以备生产数据库发生故障时,能切换到应急数据库,保证业务的正常运行。由于移动公司的数据量非常大,所以只需要对基础数据和关键数据进行备份,为了确保切换到应急数据库时保证核心业务能够运行,还需要备份整个数据库结构。
系统目前需求仅要求支持Oracle数据库的同步,但系统设计时需要考虑以后可以方便地支持其他数据库。Oracle数据库的结构由各种数据库对象组成,要求完成对各种数据库对象的同步,包括表(包括约束)、索引、触发器、分区表、视图、存储过程、函数、包、数据库连接、序列、物化视图和同义词。各类数据库对象的同步有一定的顺序关系,总体流程如图1所示:
图1 数据库同步流程图
数据库同步系统界面如图2所示:
图2 数据库同步系统界面
用户在操作界面指定源数据库、目标数据库、控制数据库(用于读取配置信息)的数据库连接串,同时选取需要同步的数据库对象类型,对象类型存储在配置文件database_syn_config.xml中,通过输入SQL语句可以获取需要同步的表数据。
数据库对象同步的处理逻辑描述如下:
(1) 对于一般的数据库对象,同步时先取出源数据库与目标数据库该类数据库对象进行对比,然后将对象更新到目标数据库。
(2) 对于DBLink对象,由于数据库环境发生变化,需要手工调整,同步过程只记录新增的DBLink信息,而不执行创建操作。
(3) 表的同步处理由于其包含数据,因此较为特殊,需先对表结构变化进行分析,再同步数据。表数据的同步有三种方式:增量同步、先Delete后Insert方式、临时表方式。
(I) 增量同步。适用于可确定最后修改时间戳字段的情况。
(II) 先Delete后Insert方式。即先删除表的数据,再将源数据库的该表数据插入到目标数据库,为确保数据安全,要求在一个事务内完成。
(III) 临时表方式。用于最大限度保证数据的完整性,是一种在发生意外情况时,不丢失数据而使用的较为复杂的方式。
由于对数据库结构修改无法做事务回滚,因此如果后面的步骤发生异常,需要通过手工编码方式来实现目标数据库结构变化的回滚。
在本系统实现过程中使用了多种设计模式,下面对其进行简要分析(为了简化代码和类图,省略了关于包的描述,在实际应用中已将不同的类封装在不同包中):
在本系统实现时提供了一个数据库同步流程管理器DBSynchronizeManager类,它用于负责控制数据库同步的具体执行步骤。用户在前台界面可以配置同步参数,程序运行时,需要根据这些参数来创建DBSynchronizeManager对象,创建完整DBSynchronizeManager对象的过程由类DBSynchronizeManagerBuilder负责,此时可以使用建造者模式来一步一步构造一个完整的复杂对象,类图如图3所示:
图3 建造者模式实例类图
在图3中省略了抽象建造者,DBSynchronizeManagerDirector充当指挥者类,DBSynchronizeManagerBuilder充当建造者,DBSynchronizeManager充当复杂产品。
DBSynchronizeManagerBuilder类的buildLife()方法可以创建一个初始的DBSynchronizeManager实例,再一步一步为其设置属性,为了保证在更换数据库时无须修改DBSynchronizeManagerBuilder类的源代码,在此处使用简单工厂模式进行设计,将数据库类型存储在配置文件中,如下片段代码所示:
……
<dbSynchronizeManager dbType="oracle" class="com. chinacreator.dbSyn.oracle.OracleDB SynchronizeManager"/>
……
类图如图4所示:
图4 简单工厂模式实例类图
使用简单工厂模式设计的工厂类DBSynchronizeManagerFactory代码如下所示:
public class DBSynchronizeManagerFactory {
public static DBSynchronizeManager factory(String dbType) throws Exception {
String className = DBSynConfigParser.getSynchronizeManagerClass(dbType);
return (DBSynchronizeManager)Class.forName(className).newInstance();
}
}
其中DBSynConfigParser类用于读取配置文件,在图4中,DBSynchronizeManagerFactory类充当数据库同步流程管理器的简单工厂,DBSynchronizeManager是抽象产品,而OracleDBSynchronizeManager为具体产品。