軟件設計模式學習(十一)橋接模式

橋接模式

橋接模式用一種很巧妙的方式處理繼承存在的問題,用抽象關聯取代了傳統的多層繼承,將類之間的靜態繼承關係轉換爲動態的對象組合關係,使得系統更加靈活,並易於擴展,同時有效地控制了系統中類的個數。


模式動機

設想如果要繪製矩形、圓形、橢圓、正方形,我們至少需要四個形狀類,如果繪製的圖形需要具有不同的顏色,如紅色、綠色、藍色等,此時至少有兩種設計方案:第一種是爲每一個行政都提供一套各種顏色的版本,這種方案使用的是多級繼承結構,如果有四種形狀,十二種顏色,則我們需要四十八個類。如果要增加新形狀則同時也要具備所有的顏色,增加新的顏色也要爲所有的形狀添加對應顏色的子類;第二種提供四個形狀類、十二種顏色類,根據實際對形狀和顏色進行組合,此時系統中的類是十六個。如需增加新的形狀或顏色,只需再增加一個新的形狀類或顏色類即可。

很明顯,對於有兩個變化維度(即兩個變化的原因)的系統,採用方案二可以使系統中類的個數更少,且系統擴展更爲方便。


模式定義

將抽象部分與它的實現部分分離,使它們都可以獨立地變化


模式結構

在這裏插入圖片描述

橋接模式包含如下幾個角色:

  1. Abstraction(抽象類)

    用於定義抽象類的接口,它一般是抽象類而不是接口,其中定義一個Implementor類型對象使其與implementor之間具有關聯關係,它可以包含抽象的業務方法,還可以包含具體的業務方法。

  2. RefineAbstraction(擴充抽象類)

    擴充由Abstraction定義的接口,通常情況下是具體類,實現在Abstraction中定義的抽象業務方法,在RefineAbstraction可以調用Implementor中定義的業務方法。

  3. Implementor(實現類接口)

    對一些基本操作進行了定義,而具體實現交給其子類。

  4. ConcreteImplementorA(具體實現類)

    實現Implementor接口並且具體實現它,在不同的ConcreteImplementor中提供基本操作的不同實現,在程序運行時ConcreteImplementor對象將替換其父類對象,提供給客戶具體的業務操作方法。


橋接模式實例之模擬毛筆

  1. 實例說明

    現需提供大小兩種型號的畫筆,能繪製三種不同的顏色,只需五個類就能實現功能。

  2. 實例代碼及解釋

    1. 實現類接口Color

      public interface Color {
      
          void bepaint(String penType, String name);
      }
      
    2. 具體實現類Red

      public class Red implements Color {
      
          @Override
          public void bepaint(String penType, String name) {
              System.out.println(penType + "紅色的" + name);
          }
      }
      
    3. 具體實現類Green

      public class Green implements Color {
      
          @Override
          public void bepaint(String penType, String name) {
              System.out.println(penType + "綠色的" + name);
          }
      }
      
    4. 具體實現類Blue

      public class Blue implements Color {
      
          @Override
          public void bepaint(String penType, String name) {
              System.out.println(penType + "藍色的" + name);
          }
      }
      
    5. 抽象類Pen

      public abstract class Pen {
      
          protected Color color;
      
          public void setColor(Color color) {
              this.color = color;
          }
      
          public abstract void draw(String name);
      }
      
    6. 擴充抽象類BigPen

      public class BigPen extends Pen {
      
          @Override
          public void draw(String name) {
              String penType = "大號毛筆繪製";
              this.color.bepaint(penType, name);
          }
      }
      
    7. 擴充抽象類SmallPen

      public class SmallPen extends Pen {
      
          @Override
          public void draw(String name) {
              String penType = "小號毛筆繪製";
              this.color.bepaint(penType, name);
          }
      }
      
    8. XML操作工具

      public class XMLUtilPen {
      
          public static Object getBean(String args) {
      
              try {
                  DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
                  DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
      
                  Document document = documentBuilder.parse(new File("configPen.xml"));
                  NodeList nodeList = document.getElementsByTagName("className");
                  Node classNode = null;
      
                  if (args.equals("color")) {
                      classNode = nodeList.item(0).getFirstChild();
                  } else if (args.equals("pen")) {
                      classNode = nodeList.item(1).getFirstChild();
                  }
      
                  String cName = classNode.getNodeValue();
      
                  Class c = Class.forName("com.bridgePattern." + cName);
                  Object o = c.newInstance();
                  return o;
      
              } catch (Exception e) {
                  e.printStackTrace();
                  return null;
              }
      
          }
      }
      
    9. 客戶端測試類Client

      public class Client {
      
          public static void main(String[] args) {
      
              Color color = (Color) XMLUtilPen.getBean("color");
              Pen pen = (Pen) XMLUtilPen.getBean("pen");
      
              pen.setColor(color);
              pen.draw("桃花");
          }
      }
      
    10. 結果分析

      如果在配置文件將第一個節點中內容設置爲 Red,第一個節點中內容設置爲 BigPen,則輸出結果如下:
      在這裏插入圖片描述
      如果在配置文件將第一個節點中內容設置爲 Blue,第一個節點中內容設置爲 SmallPen,則輸出結果如下:
      在這裏插入圖片描述
      如果需要增加新的毛筆或顏色,只需增加對應的擴充抽象類或具體實現類即可。在使用橋接模式設計的系統中,無論是哪個維度的擴展,對原有代碼都無須修改,且更換具體類只需修改配置文件,橋接模式通過抽象方法耦合,使得系統具有良好的擴展能力。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章