我的漫漫程序之旅

          專注于JavaWeb開發
          隨筆 - 39, 文章 - 310, 評論 - 411, 引用 - 0
          數據加載中……

          java設計模式之Bridge

           

          Bridge定義 :
          將抽象和行為劃分開來,各自獨立,但能動態的結合.

          為什么使用?
          通常,當一個抽象類或接口有多個具體實現(concrete subclass),這些concrete之間關系可能有以下兩種:
          1. 這多個具體實現之間恰好是并列的,如前面舉例,打樁,有兩個concrete class:方形樁和圓形樁;這兩個形狀上的樁是并列的,沒有概念上的重復,那么我們只要使用繼承就可以了.

          2.實際應用上,常常有可能在這多個concrete class之間有概念上重疊.那么需要我們把抽象共同部分和行為共同部分各自獨立開來,原來是準備放在一個接口里,現在需要設計兩個接口,分別放置抽象和行為.

          例如,一杯咖啡為例,有中杯和大杯之分,同時還有加奶 不加奶之分. 如果用單純的繼承,這四個具體實現(中杯 大杯 加奶 不加奶)之間有概念重疊,因為有中杯加奶,也有中杯不加奶, 如果再在中杯這一層再實現兩個繼承,很顯然混亂,擴展性極差.那我們使用Bridge模式來實現它.

          如何實現?
          以上面提到的咖啡 為例. 我們原來打算只設計一個接口(抽象類),使用Bridge模式后,我們需要將抽象和行為分開,加奶和不加奶屬于行為,我們將它們抽象成一個專門的行為接口.

          先看看抽象部分的接口代碼:

          package com.pattern.bridge;

          public abstract class Coffee
          {
              
          // CoffeeImp(行為)的引用
              private CoffeeImp coffeeImp;

              
          public CoffeeImp getCoffeeImp()
              
          {
                  
          return coffeeImp;
              }


              
          public void setCoffeeImp(CoffeeImp coffeeImp)
              
          {
                  
          this.coffeeImp = coffeeImp;
              }


              
          abstract void pourCoffee();
          }



          其中CoffeeImp 是加不加奶的行為接口,看其代碼如下:

          package com.pattern.bridge;

          /*******************************************************************************
           * 咖啡的行為接口
           * 
           * 
          @author zdw
           * 
           
          */

          public abstract class CoffeeImp
          {
              
          // 沖咖啡
              public abstract void pourCoffeeImp();
          }


          現在我們有了兩個抽象類,下面我們分別對其進行繼承,實現concrete class:

          package com.pattern.bridge;
          /**
           *  中杯
           * 
          @author zdw
           *
           
          */

          public class MediumCoffee extends Coffee
          {

              @Override
              
          void pourCoffee()
              
          {
                  
          //我們以重復次數來說明是沖中杯還是大杯 ,重復2次是中杯
                  for(int i = 0; i < 2; i ++)
                  
          {
                      
          this.getCoffeeImp().pourCoffeeImp();
                  }

              }


          }


          package com.pattern.bridge;
          /**
           * 大杯
           * 
          @author zdw
           *
           
          */

          public class SuperSizeCoffee extends Coffee
          {

              @Override
              
          void pourCoffee()
              
          {
                  
          for(int i = 0; i < 3; i ++)
                  
          {
                      
          this.getCoffeeImp().pourCoffeeImp();
                  }

              }


          }


          上面分別是中杯和大杯的具體實現.下面再對行為CoffeeImp進行繼承:

           
          
          package com.pattern.bridge;
          /**
           * 加牛奶行為
           * 
          @author zdw
           *
           
          */

          public class MilkCoffeeImp extends CoffeeImp
          {

              @Override
              
          public void pourCoffeeImp()
              
          {
                  System.out.println(
          "加了牛奶的咖啡!");
              }


          }
          package com.pattern.bridge;
          /**
           * 未加牛奶
           * 
          @author zdw
           *
           
          */

          public class FragrantCoffeeImp extends CoffeeImp
          {

              @Override
              
          public void pourCoffeeImp()
              
          {
                  System.out.println(
          "未加牛奶的咖啡!");
              }


          }


          Bridge模式的基本框架我們已經搭好了,別忘記定義中還有一句:動態結合,我們現在可以喝到至少四種咖啡:
          1.中杯加奶
          2.中杯不加奶
          3.大杯加奶
          4.大杯不加奶

          看看是如何動態結合的:
          package com.pattern.bridge;

          public class Client
          {
              
          public static void main(String[] args)
              
          {
                  
          //牛奶
                  CoffeeImp coffeeImp = new MilkCoffeeImp();
                  
          //未加牛奶
                  CoffeeImp coffeeImp2 = new FragrantCoffeeImp();
                  
                  System.out.println(
          "中杯");
                  
          //中杯加奶(二次)
                  Coffee coffee = new MediumCoffee();
                  coffee.setCoffeeImp(coffeeImp);
                  coffee.pourCoffee();
                  System.out.println(
          "***************中杯未加奶");
                  coffee.setCoffeeImp(coffeeImp2);
                  coffee.pourCoffee();
                  
                  System.out.println(
          "***************大杯");
                  
          //大杯加奶(三次)
                  coffee = new SuperSizeCoffee();
                  coffee.setCoffeeImp(coffeeImp);
                  coffee.pourCoffee();
                  System.out.println(
          "**************大杯未加奶");
                  
          //設置為未加奶
                  coffee.setCoffeeImp(coffeeImp2);
                  coffee.pourCoffee();
                  
                  
              }

          }


          注意: Bridge模式的執行類如CoffeeImp和Coffee是一對一的關系, 正確創建CoffeeImp是該模式的關鍵,

          Bridge模式在EJB中的應用
          EJB中有一個Data Access Object (DAO)模式,這是將商業邏輯和具體數據資源分開的,因為不同的數據庫有不同的數據庫操作.將操作不同數據庫的行為獨立抽象成一個行為接口DAO.如下:

          1.Business Object (類似Coffee)

          實現一些抽象的商業操作:如尋找一個用戶下所有的訂單

          涉及數據庫操作都使用DAOImplementor.

          2.Data Access Object (類似CoffeeImp)

          一些抽象的對數據庫資源操作

          3.DAOImplementor
           如OrderDAOCS, OrderDAOOracle, OrderDAOSybase(類似MilkCoffeeImp FragrantCoffeeImp)

          具體的數據庫操作,如"INSERT INTO "等語句,OrderDAOOracle是Oracle OrderDAOSybase是Sybase數據庫.

          4.數據庫 (Cloudscape, Oracle, or Sybase database via JDBC API)

          UML類圖如下:


          posted on 2008-05-26 10:38 々上善若水々 閱讀(1351) 評論(0)  編輯  收藏 所屬分類: 設計模式

          主站蜘蛛池模板: 嵊州市| 张家口市| 汾阳市| 梁山县| 阳新县| 华阴市| 汕头市| 喀喇| 龙州县| 屏边| 定州市| 奉化市| 松阳县| 呼玛县| 彰武县| 黑河市| 沧州市| 涞源县| 永年县| 锦屏县| 鹤壁市| 渑池县| 云林县| 新田县| 建宁县| 渭源县| 峡江县| 北川| 湖南省| 五峰| 集贤县| 望谟县| 邢台市| 禹州市| 修文县| 巴马| 滦平县| 高碑店市| 辽中县| 嘉义市| 墨玉县|