熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java高級技術 >> 正文

java設計模式之Bridge(抽象和行為分開)

2013-11-23 19:51:19  來源: Java高級技術 

  Bridge定義 :
  將抽象和行為劃分開來各自獨立但能動態的結合
  
  為什麼使用?
  通常當一個抽象類或接口有多個具體實現(concrete subclass)這些concrete之間關系可能有以下兩種:
   這多個具體實現之間恰好是並列的如前面舉例打樁有兩個concrete class:方形樁和圓形樁;這兩個形狀上的樁是並列的沒有概念上的重復那麼我們只要使用繼承就可以了
  
  實際應用上常常有可能在這多個concrete class之間有概念上重疊那麼需要我們把抽象共同部分和行為共同部分各自獨立開來原來是准備放在一個接口裡現在需要設計兩個接口分別放置抽象和行為
  
  例如一杯咖啡為例有中杯和大杯之分同時還有加奶 不加奶之分 如果用單純的繼承這四個具體實現(中杯 大杯 加奶 不加奶)之間有概念重疊因為有中杯加奶也有中杯不加奶 如果再在中杯這一層再實現兩個繼承很顯然混亂擴展性極差那我們使用Bridge模式來實現它
  
  如何實現?
  以上面提到的咖啡 為例 我們原來打算只設計一個接口(抽象類)使用Bridge模式後我們需要將抽象和行為分開加奶和不加奶屬於行為我們將它們抽象成一個專門的行為接口
  
  先看看抽象部分的接口代碼:
  
  public abstract class Coffee
  {
    CoffeeImp coffeeImp;
  
    public void setCoffeeImp() {
      thisCoffeeImp = CoffeeImpSingletongetTheCoffeImp();
    }
  
    public CoffeeImp getCoffeeImp() {return thisCoffeeImp;}
  
    public abstract void pourCoffee();
  }
  
  其中CoffeeImp 是加不加奶的行為接口看其代碼如下:
  
  public abstract class CoffeeImp
  {
    public abstract void pourCoffeeImp();
  }
   
  現在我們有了兩個抽象類下面我們分別對其進行繼承實現concrete class:
  
  //中杯
  public class MediumCoffee extends Coffee
  {
    public MediumCoffee() {setCoffeeImp();}
  
    public void pourCoffee()
    {
      CoffeeImp coffeeImp = thisgetCoffeeImp();
      //我們以重復次數來說明是沖中杯還是大杯 重復次是中杯
      for (int i = ; i < ; i++)
      {
  
        coffeeImppourCoffeeImp();
      }
    
    }
  }
  
  //大杯
  public class SuperSizeCoffee extends Coffee
  {
    public SuperSizeCoffee() {setCoffeeImp();}
  
    public void pourCoffee()
    {
      CoffeeImp coffeeImp = thisgetCoffeeImp();
      //我們以重復次數來說明是沖中杯還是大杯 重復次是大杯
      for (int i = ; i < ; i++)
      {
  
        coffeeImppourCoffeeImp();
      }
    
    }
  }
  
  上面分別是中杯和大杯的具體實現下面再對行為CoffeeImp進行繼承:
  
  //加奶
  public class MilkCoffeeImp extends CoffeeImp
  {
    MilkCoffeeImp() {}
  
    public void pourCoffeeImp()
    {
      Systemoutprintln(加了美味的牛奶);
    }
  }
  
  //不加奶
  public class FragrantCoffeeImp extends CoffeeImp
  {
    FragrantCoffeeImp() {}
  
    public void pourCoffeeImp()
    {
      Systemoutprintln(什麼也沒加清香);
    }
  }
  
  Bridge模式的基本框架我們已經搭好了別忘記定義中還有一句:動態結合我們現在可以喝到至少四種咖啡:
  中杯加奶
  中杯不加奶
  大杯加奶
  大杯不加奶
  
  看看是如何動態結合的在使用之前我們做個准備工作設計一個單態類(Singleton)用來hold當前的CoffeeImp:
  
  public class CoffeeImpSingleton
  {
    private static CoffeeImp coffeeImp;
  
    public CoffeeImpSingleton(CoffeeImp coffeeImpIn)
     {ffeeImp = coffeeImpIn;}
  
    public static CoffeeImp getTheCoffeeImp()
    {
      return coffeeImp;
    }
  }
  
  看看中杯加奶 和大杯加奶 是怎麼出來的:
  
  //拿出牛奶
  CoffeeImpSingleton coffeeImpSingleton = new CoffeeImpSingleton(new MilkCoffeeImp());
  
  //中杯加奶
  MediumCoffee mediumCoffee = new MediumCoffee();
  mediumCoffeepourCoffee();
  
  //大杯加奶
  SuperSizeCoffee superSizeCoffee = new SuperSizeCoffee();
  superSizeCoffeepourCoffee();
  
  注意: Bridge模式的執行類如CoffeeImp和Coffee是一對一的關系 正確創建CoffeeImp是該模式的關鍵
  
  Bridge模式在EJB中的應用
  EJB中有一個Data Access Object (DAO)模式這是將商業邏輯和具體數據資源分開的因為不同的數據庫有不同的數據庫操作將操作不同數據庫的行為獨立抽象成一個行為接口DAO如下:
  
  Business Object (類似Coffee)
  
  實現一些抽象的商業操作:如尋找一個用戶下所有的訂單
  
  涉及數據庫操作都使用DAOImplementor
  
  Data Access Object (類似CoffeeImp)
  
  一些抽象的對數據庫資源操作
  
  DAOImplementor 如OrderDAOCS OrderDAOOracle OrderDAOSybase(類似MilkCoffeeImp FragrantCoffeeImp)
  
  具體的數據庫操作INSERT INTO 等語句OrderDAOOracle是Oracle OrderDAOSybase是Sybase數據庫
  
  數據庫 (Cloudscape Oracle or Sybase database via JDBC API)
From:http://tw.wingwit.com/Article/program/Java/gj/201311/27565.html
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.