点击这里给我发消息 点击这里给我发消息

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

添加时间:2013-12-7
    相关阅读: 设计 WEB 数据库 SQL Oracle 公司 维护

  从重构的角度学习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();
  }
咨询热线:020-85648757 85648755 85648616 0755-27912581 客服:020-85648756 0755-27912581 业务传真:020-32579052
广州市网景网络科技有限公司 Copyright◎2003-2008 Veelink.com. All Rights Reserved.
广州商务地址:广东省广州市黄埔大道中203号(海景园区)海景花园C栋501室
= 深圳商务地址:深圳市宝源路华丰宝源大厦606
研发中心:广东广州市天河软件园海景园区 粤ICP备05103322号 工商注册