从重构的角度学习bridge设计模式 (转)

从重构的角度学习bridge设计模式 (转)[@more@]从重构的角度学习bridge设计 模式

Bridge模式是一个在实际 系统中经常应用的模式。它最能体现设计模式的原则
针对接口进行 编程,和使用聚合不使用继承这两个原则。


由于我们过分的使用继承,使类的结构过于复杂,不易理解,难以维护。特别
是在 Java中由于不能同时继承多个类,这样就会造成多层继承,维护更难。
Bridge模式是解决多层继承的根本原因。如果你在实现应用中一个类,需要继承
两个以上的类,并且这两者之间又持有某种关系,它们两个都会有多种变化。
Bridge模式是把这两个类,分解为一个抽象,一个实现,使它们两个分离,这样
两种类可以独立的变化。
抽象就是,把一个实体的共同概念(相同的步骤),抽取出来(分解出几个相互独立的步骤),
作为一个过程。如我们把 数据库的 操作抽象为一个过程,有几个步骤,创建 sql语句,
发送到数据库处理,取得结果。

实现就是怎样完成这个抽象步骤,如发送到数据库,需要结合具体的数据库,考虑怎样完成这个步骤等。
并且同一步骤可能存在不同的实现,如对不同的数据库需要不同的实现。

现在我们假设一个情况,也是 web中经常遇到的,在一个page有输入框,
如客户信息的姓名,地址等,输入信息后,然后按查找按钮,把查找的结果显示出来。
我们现在假设查找客户信息和帐户信息,它们在不同的表中。
但是我们的系统面对两种人群,总部的它们信息保存到 ORACLE数据库,但是各个分公司
的数据保存在 Sybase中,数据库的位置等各不相同,这两种的操作不同。

下面是我们一般首先会使用的方式,使用if else进行,判断,这样使用系统
难以维护,难以扩展,不妨你增加一种查询,或者一种数据库试试????
public class SearchAction(){
public Vector searchData(string ActionType,String dbType){
String SQL="";
if(ActionType.equal("查找客户信息")){
//如果是查询客户信息,拼SQL语句从客户表中读取数据
SQL=" select * from Customer "

if(dbType.equal("oracle")){
//从总部数据库读取,数据库为Oracle
String connect_string =" JDBC:oracle:thin:hr/hr@localhost:1521:HRDB";
driverManager.registerDriver (new oracle.jdbc.OracleDriver());
Connection conn = DriverManager.getConnection (connect_string);
// Create a statement
Statement stmt = conn.createStatement ();
ResultSet rset = stmt.executeQuery (SQL);
//以下省略部分动态从数据库中取出数据,组装成Vector,返回
..................................
...................................
}else(dbType.equal("sybase")){
//从分公司数据库读取,数据库为Sybase
String connect_string ="jdbc:sybase:Tds:cai/cai@192.168.1.12:1521:FIN";
DriverManager.registerDriver (new com.sybase.jdbc.SybDriver());
Connection conn = DriverManager.getConnection (connect_string);
// Create a statement
Statement stmt = conn.createStatement ();
ResultSet rset = stmt.executeQuery (SQL);
//以下省略部分动态从数据库中取出数据,组装成Vector,返回
..................................
...................................

}

}else if(ActionType.equal("查找帐户信息")){
//如果是查询帐户信息,拼接SQL语句从帐户表中读取数据
SQL="select * from Account "
if(dbType.equal("oracle")){
..........................
..........................
(作者注:此处省略从oracle读取,约300字)

}else if(dbType.equal("Sybase")){
..........................
..........................
(作者注:此处省略从Sybase读取,约300字)
}

}
}
}

如果你认为这写的比较弱智,应该进行使用 函数,但是你也会大量使用if else.???

于是我们进行重构,首先我们学习过DAO模式,就是把数据读取进行分里,我们定义一个
共同的接口,它负责数据库的操作,然后根据不同的数据库进行实现,在我们的查询操作中,
使用接口,进行操作,这样就可以不用考虑具体的实现,我们只管实现过程。

查询共同接口:
public interface searchDB{
public Vector searchFromDB(String SQL)
}
Oracle数据库的查询实现
public class searchDBOracleImpl{
public Vector searchFromDB(String SQL){
//从总部数据库读取,数据库为Oracle
String connect_string ="jdbc:oracle:thin:hr/hr@localhost:1521:HRDB";
DriverManager.registerDriver (new oracle.jdbc.OracleDriver());

ResultSet rset = stmt.executeQuery (SQL);
.............................
............................

}
}
Sybase数据库的查询实现
public class searchDBSysbaseImpl{
public Vector searchFromDB(String SQL){
//从分公司数据库读取,数据库为Sysbase
String connect_string ="jdbc:sybase:Tds:cai/cai@192.168.1.12:1521:FIN";
DriverManager.registerDriver (new com.sybase.jdbc.SybDriver());
ResultSet rset = stmt.executeQuery (SQL);
.............................
............................

}
}

这样在我们的查询中就可以使用接口searchDB,但是创建有是一个问题,因为我们不能
静态的确定,查询的数据库类型,必须动态确定,于是我们又想到使用简单工厂方法,
来分别创建这里的具体实现,根据类别,创建
public class searchFactory{
public static searchDB createSearch(int DBType){
if(DBType.equal("oracle")){
return searchDBOracleImpl();
}else if(DBType.equal("sybase")){
return searchDBSysbaseImpl();
}
}
}
于是我们的查询代码可以改变为这样了;
public class SearchAction(){

public Vector searchData(string ActionType,String DbType){
String SQL="";
if(ActionType.equal("查找客户信息")){
//如果是查询客户信息,拼SQL语句从客户表中读取数据
SQL="select * from Customer "
searchDB obj=searchFactory.createSearch(DbType);
return obj.searchFromDB(SQL);

}else if(ActionType.equal("查找帐户信息")){
//如果是查询帐户信息,拼接SQL语句从帐户表中读取数据
SQL="select * from Account "
searchDB obj=searchFactory.createSearch(DbType);
return obj.searchFromDB(SQL);
}
}
}
是不是简单一些,如果增加一个新的数据库,对我们只需增加一个新的数据库实现便可,
老的代码,不需改变,这样便实现开-闭原则(Open-closed原则),在我们的查询查询
中使用的是接口,这就是设计模式的原则,针对接口进行编程,并且使用聚合,而不是直接的继承
大家,可以考虑使用继承来完成该工作怎样实现?????

上面是把实现进行分离,实现可以动态变化!!!!!

我们把查询的操作的具体数据库实现进行了分离,增强了灵活性,但是我们的查询。
仍然使用了if else这样仍然不易进行扩展,于是我们进行抽象一个查询操作的过程,
把它分成几个具体步骤,创建SQL语句,发送到数据库, 执行查询,返回结果。
它们虽然是不同的查询,SQL各不相同,不同数据库执行不同,返回结果的内容不同。但是
这个过程却是不变的,于是我们声明一个抽象类,来完成这个过程。

public abstract class searchAction{
searchDB obj;
//两个步骤
public searchDB createSearchImple(int DbType){
return searchFactory.createSearch(DbType);
}
public abstract String createSQL();

//查询过程,最后返回结果
public vector searchResult(int DbType){
obj=createSearchImple(DbType);
return obj.searchFromDB(createSQL())
}
}

//我们客户查询,操作
public class searchCustomerAction{
public String createSQL(){
return "select * from Customer"
}
}
//我们的帐户查询操作
public class searchAccountAction{
public String createSQL(){
return "select * from account"
}
}

这样我们的查询编程简单的创建SQL语句,我们应该再创建一个工厂方法,
来完成创建它们
public class actionFactory{
public static searchAction ceateAction(int actionType){
if(actionType.equal("customer")){
return searchCustomerAction();
}else if(actionType.equal("account")){
return searchAccountAction();
}
}
}
这样我们把查询操作的过程进行了抽象,定义了步骤,和具体过程,经过我们的两次改变
把抽象部分和实现部分进行分离,使他们都可以独立的变化,增强灵活性。
我们再看当初查询实现,现在经过这两次的地修改,变成了什么模样?如下:

public class SearchAction(){
public Vector searchData(string ActionType,String DbType){
searchAction action=actionFactory.ceateAction(ActionType);
return action.searchResult(DbType);
}
现在假如增加一个数据库类型,将会改变那些??,如果增加一种查询操作需要改变那些???

讨论点:
1:在我们的重构过程中,
怎样使用设计模式原则的???
现在如果增加功能,遵循开闭原则吗??
2:我们使用了两个简单工厂,这是为了简化,一般最好使用抽象工厂方法,
如果改为抽象工厂,怎样修改???



我打算写一系列的文章介绍设计模式,
希望从重构的角度考虑模式的应用,而不是
直接介绍模式,这样对初学者容易 入门,step by step。
如果在自己的代码中遇到类似的情景,可以进行重构。


从重构学习 Proxy,预告
为什么 EJB有Home,remote,bean这三种角色?
为什么又客户端与容器进行交互??
介绍在EJB中的应用???

从重构学习decorator??

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/10752019/viewspace-958850/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/10752019/viewspace-958850/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值