軟件設計模式修煉 -- 橋接模式


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


模式動機

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

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


模式定義

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


模式結構

在這裏插入圖片描述

橋接模式包含以下幾個角色:測試

  1. Abstraction(抽象類)ui

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

  2. RefineAbstraction(擴充抽象類)設計

    擴充由Abstraction定義的接口,一般狀況下是具體類,實如今Abstraction中定義的抽象業務方法,在RefineAbstraction能夠調用Implementor中定義的業務方法。code

  3. Implementor(實現類接口)xml

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

  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,則輸出結果以下:
      在這裏插入圖片描述 若是須要增長新的毛筆或顏色,只需增長對應的擴充抽象類或具體實現類便可。在使用橋接模式設計的系統中,不管是哪一個維度的擴展,對原有代碼都無須修改,且更換具體類只需修改配置文件,橋接模式經過抽象方法耦合,使得系統具備良好的擴展能力。

相關文章
相關標籤/搜索