分享
 
 
 

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

王朝java/jsp·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

从重构的角度学习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??

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有