設計模式(七)橋接

冬先生發表於2023-10-08

一、定義

將抽象部分與它的實現部分解耦,使兩者都能夠獨立變化,橋接模式是一種結構型模式。

二、描述

包含以下四個角色:
1、Abstraction(抽象類):它是用於定義抽象類的介面,通常是抽象類而不是介面,其中定義了一個Implementor(實現類介面)型別的物件並可以維護該物件,它與Implementor之間具有關聯關係,既可以包含抽象業務方法,也可以包含具體業務方法。
2、RefinedAbstratction(擴充抽象類):它擴充由Abstraction定義的介面,通常情況下他不再是抽象類而是具體類,實現了在Abstraction中宣告的抽象業務方法,在RefinedAbstraction中可以呼叫在Implementor中定義的業務方法。
3、Implementor(實現類介面):它是定義實現類的介面,這個介面不一定要與Abstraction的介面完全一致,事實上兩個介面可以完全不同。一般而言,Implementor只提供基本操作,而Abstraction定義的介面可能會做更多更復雜的操作。Implementor介面對這些基本操作進行了宣告,而將具體實現交給其子類。透過關聯關係,在Abstraction中不僅可以擁有自己的方法,還可以呼叫Implementor中定義的方法,使用關聯關係來替代繼承關係。
4、ConcreteImplementor(具體實現類):它具體實現Implementor介面,在不同的ConcreteImplementor中提供基本操作的不同實現,在程式執行時,ConcreteImplentor物件將替換其父類物件,提供給抽象類具體的業務操作方法。

三、例子

X公司想要開發一個跨平臺的影像瀏覽系統,要求該系統能夠顯示JPG、BMP、GIF、PNG等多種格式的檔案,並且能夠在Windows、Linux以及Unix等多個作業系統上執行。該系統首先將各種格式的檔案解析為畫素矩陣(Matrix),然後將畫素矩陣顯示在螢幕上,在不同的作業系統中可以呼叫不同的繪製函式來繪製畫素矩陣。該系統需要具備較好的擴充套件性以支援新的檔案格式和作業系統。Matrix:畫素矩陣類,輔助類,各種格式的影像檔案最終都會被轉化為畫素矩陣,不同的作業系統提供不同的方式顯示畫素矩陣

public class Matrix
{
    // 省略實現程式碼
}

Image:抽象影像類,充當抽象類

public abstract class Image
{
    protected ImageImplementor imageImpl;

    public void SetImageImplementor (ImageImplementor imageImpl)
    {
        this.imageImpl = imageImpl;
    }

    public abstract void ParstFile(string fileName);
}

JPGImage、BMPImage、GIFImage:擴充抽象類

public class JPGImage : Image
{
    public override void ParstFile(string fileName)
    {
        // 模擬解析JPG檔案並獲得一個畫素矩陣物件m
        Matrix m = new Matrix();
        imageImpl.DoPaint(m);
        Console.WriteLine("{0} : 格式為JPG", fileName);
    }
}

public class BMPImage : Image
{
    public override void ParstFile(string fileName)
    {
        // 模擬解析BMP檔案並獲得一個畫素矩陣物件m
        Matrix m = new Matrix();
        imageImpl.DoPaint(m);
        Console.WriteLine("{0} : 格式為BMP", fileName);
    }
}

public class GIFImage : Image
{
    public override void ParstFile(string fileName)
    {
        // 模擬解析GIF檔案並獲得一個畫素矩陣物件m
        Matrix m = new Matrix();
        imageImpl.DoPaint(m);
        Console.WriteLine("{0} : 格式為GIF", fileName);
    }
}

ImageImplementor:抽象作業系統實現類

public interface ImageImplementor
{
    // 顯示畫素矩陣
    void DoPaint(Matrix m);
}

WindowsImplementor、LinuxImplementor、UnixImplementor:具體實現類

public class WindowsImplementor : ImageImplementor
{
    public void DoPaint(Matrix m)
    {
        // 呼叫Windows的繪製函式繪製畫素矩陣
        Console.WriteLine("在Windows系統中顯示影像");
    }
}

public class LinuxImplementor : ImageImplementor
{
    public void DoPaint(Matrix m)
    {
        // 呼叫Linux的繪製函式繪製畫素矩陣
        Console.WriteLine("在Linux系統中顯示影像");
    }
}

public class UnixImplementor : ImageImplementor
{
    public void DoPaint(Matrix m)
    {
        // 呼叫Unix的繪製函式繪製畫素矩陣
        Console.WriteLine("在Unix系統中顯示影像");
    }
}

Program:測試程式碼

Matrix m = new Matrix();
ImageImplementor wi = new WindowsImplementor();
Image ji = new JPGImage();
ji.SetImageImplementor(wi);
ji.ParstFile("小龍女");
Console.ReadLine();

四、總結

1、優點

(1)分離抽象介面及其實現部分,橋接模式使用“物件間的關聯關係”解耦了抽象和實現之間固有的繫結關係,使得抽象和實現可以沿著各自的維度變化。
(2)取代多層繼承方案,極大地減少了子類的個數。
(3)提高了系統可擴充套件性,在兩個變化維度中任意擴充套件一個維度,不需要修改原有系統,符合開閉原則。

2、缺點

(1)增加了系統的理解和設計難度,需要開發者在一開始就對抽象層進行設計與程式設計。
(2)要求正確識別出系統中兩個獨立變化的維度,如何正確地識別需要一定的經驗積累。

相關文章