設計模式:橋接(Bridge)模式

設計模式之橋接(Bridge)模式

在現實生活中,某些類具有兩個或多個維度的變化,如圖形既可按形狀分,又可按顏色分。如何設計類似於 Photoshop 這樣的軟件,能畫不同形狀和不同顏色的圖形呢?如果用繼承方式,m 種形狀和 n 種顏色的圖形就有 m×n 種,不但對應的子類很多,而且擴展困難。

當然,這樣的例子還有很多,如不同顏色和字體的文字、不同品牌和功率的汽車、不同性別和職業的男女、支持不同平臺和不同文件格式的媒體播放器等。如果用橋接模式就能很好地解決這些問題。

定義與特點

橋接(Bridge)模式的定義如下:將抽象與實現分離,使它們可以獨立變化。它是用組合關係代替繼承關係來實現,從而降低了抽象和實現這兩個可變維度的耦合度。

橋接(Bridge)模式的優點是:

  • 由於抽象與實現分離,所以擴展能力強;
  • 其實現細節對客戶透明。

缺點是:由於聚合關係建立在抽象層,要求開發者針對抽象化進行設計與編程,這增加了系統的理解與設計難度。

結構與實現

可以將抽象化部分與實現化部分分開,取消二者的繼承關係,改用組合關係。

結構

橋接(Bridge)模式包含以下主要角色。

  1. 抽象化(Abstraction)角色:定義抽象類,幷包含一個對實現化對象的引用。
  2. 擴展抽象化(Refined Abstraction)角色:是抽象化角色的子類,實現父類中的業務方法,並通過組合關係調用實現化角色中的業務方法。
  3. 實現化(Implementor)角色:定義實現化角色的接口,供擴展抽象化角色調用。
  4. 具體實現化(Concrete Implementor)角色:給出實現化角色接口的具體實現

其結構圖如圖 1 所示。

在這裏插入圖片描述

實現

package com.design.pattern.structuralPattern.bridgePattern;

public class BridgeTest {

    public static void main(String[] args) {
        Implementor implementor = new ImplementorPerson();
        Abstraction abs = new ExtensionAbstractor(implementor);
        abs.operate();
    }
}
//抽象化角色
abstract class Abstraction{
    protected Implementor implementor;

    protected Abstraction(Implementor implementor) {
        this.implementor = implementor;
    }

    public abstract void operate();
}

//實現化角色
interface Implementor{
    public void operate();
}
//具體實現化角色
class ImplementorPerson implements Implementor{


    @Override
    public void operate() {
        System.out.println("具體實現化角色被操作!");
    }
}
//擴展抽象化角色
class ExtensionAbstractor extends Abstraction{

    protected ExtensionAbstractor(Implementor implementor) {
        super(implementor);
    }

    @Override
    public void operate() {
        System.out.println("拓展抽象化角色被訪問!");
        implementor.operate();
    }
}

實例

【例1】用橋接(Bridge)模式模擬女士皮包的選購。

分析:女士皮包有很多種,可以按用途分、按皮質分、按品牌分、按顏色分、按大小分等,存在多個維度的變化,所以採用橋接模式來實現女士皮包的選購比較合適。

本實例按用途分可選錢包(Wallet)和挎包(HandBag),按顏色分可選黃色(Yellow)和紅色(Red)。可以按兩個維度定義爲顏色類和包類。

顏色類(Color)是一個維度,定義爲實現化角色,它有兩個具體實現化角色:黃色和紅色,通過 getColor() 方法可以選擇顏色;包類(Bag)是另一個維度,定義爲抽象化角色,它有兩個擴展抽象化角色:挎包和錢包,它包含了顏色類對象,通過 getName() 方法可以選擇相關顏色的挎包和錢包。

圖 2 所示是其結構圖。

在這裏插入圖片描述

程序代碼如下:

package com.design.pattern.structuralPattern.bridgePattern;

public class BagManage {

    public static void main(String[] args) {
        Color color = new Yellow();
        Bag bag = new HandBag(color);
        System.out.println(bag.getName());
        color = new Red();
        bag = new Wallet(color);
        System.out.println(bag.getName());
    }
}

interface Color{
    String getColor();
}

class Yellow implements Color{

    @Override
    public String getColor() {
        return "黃色";
    }
}

class Red implements Color{

    @Override
    public String getColor() {
        return "紅色";
    }
}

abstract class Bag{
    protected Color color;

    protected Bag(Color color) {
        this.color = color;
    }

    public void setColor(Color color){
        this.color = color;
    }
    public abstract String getName();
}

class HandBag extends Bag{

    public HandBag(Color color) {
        super(color);
    }

    @Override
    public String getName() {
        return color.getColor() + "手提包";
    }
}

class Wallet extends Bag{

    protected Wallet(Color color) {
        super(color);
    }

    @Override
    public String getName() {
        return color.getColor() + "錢包";
    }
}

應用場景

橋接模式通常適用於以下場景。

  1. 當一個類存在兩個獨立變化的維度,且這兩個維度都需要進行擴展時。
  2. 當一個系統不希望使用繼承或因爲多層次繼承導致系統類的個數急劇增加時。
  3. 當一個系統需要在構件的抽象化角色和具體化角色之間增加更多的靈活性時。

橋接模式的擴展

在軟件開發中,有時橋接(Bridge)模式可與適配器模式聯合使用。當橋接(Bridge)模式的實現化角色的接口與現有類的接口不一致時,可以在二者中間定義一個適配器將二者連接起來,其具體結構圖如圖 5 所示。

在這裏插入圖片描述

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