🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
# 设计模式综合实例分析之数据库同步系统(三) 接“设计模式综合实例分析之数据库同步系统(二)“。 6. 策略模式 由于表数据的同步方式有三种,分别是增量同步、先Delete后Insert方式、临时表方式,因此可以定义一个同步策略接口DataSynStrategy,并提供三个具体实现类:IncSynStrategy、DelAndInsSynStrategy和TempTableSynStrategy。类图如图8所示: ![](http://img.my.csdn.net/uploads/201303/14/1363226626_9216.jpg) 图8 策略模式实例类图 在图8中,Oracle表同步对象类OracleTableDBSynchronizer充当环境类,DataSynStrategy充当抽象策略类,其子类IncSynStrategy、DelAndInsSynStrategy和TempTableSynStrategy充当具体策略类。 在OracleTableDBSynchronizer中将DataSynStrategy作为方法synSingleTable()的局部变量,因此OracleTableDBSynchronizer与DataSynStrategy为依赖关系,如果为全局变量,则为关联关系。 7. 组合模式、命令模式和职责链模式 在使用临时表方式实现表同步时可以定义一系列命令对象,这些命令封装对数据库的操作,由于有些操作修改了数据库结构,因此传统的JDBC事务控制起不到作用,需要自己实现操作失败后的回滚逻辑。此时可以使用命令模式进行设计,在设计时还可以提供宏命令MacroCommand,用于将一些具体执行数据库操作的命令组合起来,形成复合命令。类图如图9所示(由于原始类图比较复杂,考虑到可读性,图9进行了适当简化,不过简化了之后还是挺复杂的): ![](http://img.my.csdn.net/uploads/201303/14/1363226681_1056.jpg) 图9 组合模式、命令模式和职责链模式实例类图 (由于涉及到多个模式的联用,此图有点点复杂) 在图9中,TempTableSynCommand充当抽象命令,MacroCommand充当宏命令类,RenameTableCommand、SynTableDataCommand和RenameTableConstraintCommand充当具体命令,TempTableSynStrategy充当请求调用者,DataSynHelper充当请求接收者,在DataSynHelper中定义了辅助实现临时表方式同步的一些方法,在命令类中将调用这些方法。在TempTableSynCommand中声明了公共的execute()方法,并提供了回滚方法undo(),其子类实现具体的执行操作与恢复操作。DataSynHelper接口声明了进行数据库操作的方法,在其子类DataSynHelperImpl中实现了这些方法。 在TempTableSynCommand中还定义了两个子类型的变量previousCommand、nextCommnad用于保存前一个命令和后一个命令,其中nextCommnad用于在执行完当前命令的业务逻辑后,再执行下一个命令的业务逻辑;而previousCommand用于在出现异常时,调用上一个命令的undo()方法实现恢复操作。此时使用了职责链模式,nextCommnad.execute()实现正向职责链,而previousCommand.undo()加上Java的异常处理机制实现反向职责链。 MacroCommand是宏命令,其代码片段如下所示: ``` public class MacroCommand extends TempTableSynCommand { TempTableSynCommand lastCommand = this; public void add(TempTableSynCommand tempTableSynCommand) { tempTableSynCommand.setPreviousCommand(lastCommand); lastCommand = tempTableSynCommand; //创建命令链 } protected void execute() throws Exception { …… } protected void undo() throws Exception { …… } } ``` 在请求调用者类TempTableSynStrategy中通过如下代码片段来调用宏命令对象的execute()方法: ``` public class TempTableSynStrategy extends DataSynStrategy { public String processSyn() { //其他代码省略 String tempTableName = generateTempTableName(); String backupTableName = "BAK_" + tempTableName; DataSynHelper dataSynHelper = new DataSynHelperImpl(); MacroCommand marcoCommand = new MacroCommand(); marcoCommand.add(new RenameTableConstraintCommand(dataSynHelper, tableName, destDB)); marcoCommand.add(new SynTableDataCommand(dataSynHelper, tableName, tempTableName, srcDB, destDB)); marcoCommand.add(new RenameTableCommand(dataSynHelper, tableName, backupTableName, destDB)); marcoCommand.add(new RenameTableCommand(dataSynHelper, tempTableName, tableName, destDB)); try{ marcoCommand.execute(); try { //其他代码省略 } catch (Exception e) { e.printStackTrace(); } } catch (Exception e){ e.printStackTrace(); } //其他代码省略 } } ``` 【本实例分析到此全部结束,希望能给各位带来帮助!】