选择显示字体大小

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

来自:http://www.jdon.com/  


从重构的角度学习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:我们使用了两个简单工厂,这是为了简化,一般最好使用抽象工厂方法,
如果改为抽象工厂,怎样修改???




 


关键字 本文所属关键字

相关 与本文相关文章

分类 所有文章关键字导航

源码编程相关

Java   Asp   PHP   .Net   XML   C/C++   CGI   VB   Jsp   J2ee   J2se   J2me   EJB   Servlet   Tomcat   Resin   Struts   Weblogic   Eclipse   ANT   GUI   JMS   Web servise   IDEA   Webphere   Hibernate   Spring   Jboss   Applet   Swing   Socket   Javamail   Perl   Ajax   P2P   安全   模式   框架   测试   开源   游戏

SQL数据库相关

My-SQL   Ms-SQL   Access   DB2   Oracle   Sybase   SQLserver   索引   存储过程   加密   数据库   分页   视图  

手机无线相关

3G   Wap   CDMA   GRPS   GSM   IVR   彩信   短信   无线   增值业务

网页设计制作相关

HTML   CSS   网页配色   网页特效   Javascript   VBscript   Dreamweaver   Frontpage   JS   Web   网站设计

网站建设推广相关

建站经验   网站优化   网站排名   推广   Alexa

操作系统/服务器相关

Windows XP   Windows 2000   Windows 2003   Windows Me   Windows 9.x   Linux   UNIX   注册表   操作系统   服务器   应用服务器

图形图像多媒体相关

Photoshop   Fireworks   Flash   Coreldraw   Illustrator   Freehand   Photoimpact   多媒体   图形图像

标准 网站致力的规范

Valid CSS!

无不良内容,无不良广告,无恶意代码

Valid XHTML 1.0 Transitional

creativecommons