1. 程式人生 > >橋接模式(Bridge Pattern)——處理多維度變化

橋接模式(Bridge Pattern)——處理多維度變化

前言

P: 嘿,小重樓!我們這邊有個簡單的需求,交個你了。

me: 啥需求?我拒絕!!!

P: 呀?你小子敢拒絕老孃的需求,活膩了吧?

me: 好吧,我接。。。做啥呢?我接。。。

P: 我這邊需要開發一個視訊播放器。不僅要跨平臺(Linux,Mac,Windows等)還要支援播放多種格式的視訊檔案(MPEG,RMVB,AVI,WMI等)哦。

me:這。。。這個要求有點太高了吧?還好現在開源專案多,可以解決技術問題。但是,這個該怎麼設計呢???

Master: 沒關係。。。我給你一個法寶,保準輕鬆解決設計問題。諾。。。橋接模式,拿去,隨便用!

概述

橋接模式(Bridge Pattern)

將抽象部分與它的實現部分分離,使它們都可以獨立地變化。它是一種物件結構型模式,又稱為柄體(Handle and Body)模式或介面(Interface)模式。

如果軟體系統中某個類存在兩個獨立變化的維度,通過該模式可以將這兩個維度分離出來,使兩者可以獨立擴充套件,讓系統更加符合“單一職責原則”。與多層繼承方案不同,它將兩個獨立變化的維度設計為兩個獨立的繼承等級結構,並且在抽象層建立一個抽象關聯,該關聯關係類似一條連線兩個獨立繼承結構的橋,故名橋接模式。

類圖

這裡寫圖片描述

Abstraction(抽象類):用於定義抽象類的介面,它一般是抽象類而不是介面,其中定義了一個Implementor(實現類介面)型別的物件並可以維護該物件,它與 Implementor 之間具有關聯關係,它既可以包含抽象業務方法,也可以包含具體業務方法。

RefinedAbstraction(擴充抽象類):擴充由 Abstraction 定義的介面,通常情況下它不再是抽象類而是具體類,它實現了在 Abstraction 中宣告的抽象業務方法,在 RefinedAbstraction 中可以呼叫在 Implementor 中定義的業務方法。

Implementor(實現類介面):定義實現類的介面,這個介面不一定要與 Abstraction 的介面完全一致,事實上這兩個介面可以完全不同,一般而言,Implementor 介面僅提供基本操作,而 Abstraction 定義的介面可能會做更多更復雜的操作。Implementor 介面對這些基本操作進行了宣告,而具體實現交給其子類。通過關聯關係,在 Abstraction 中不僅擁有自己的方法,還可以呼叫到 Implementor 中定義的方法,使用關聯關係來替代繼承關係。

ConcreteImplementor(具體實現類):具體實現 Implementor 介面,在不同的 ConcreteImplementor 中提供基本操作的不同實現,在程式執行時,ConcreteImplementor 物件將替換其父類物件,提供給抽象類具體的業務操作方法。

設計模式的實現

實現前言部分程式碼

package Bridge;

/**
 * <p>ClassName      VideoFomat
 * <p>Description    視訊格式抽象類
 * <p>Author         ChongLou
 * <p>Version
 * <p>Date           2017/11/27 0:17
 */
public interface VideoFomat {
    /**
     * 視訊解碼播放。
     */
    void decodingAndPlay();
}
package Bridge;

/**
 * <p>ClassName      SystemPlatform
 * <p>Description    系統平臺抽象類
 * <p>Author         ChongLou
 * <p>Version
 * <p>Date           2017/11/27 0:15
 */
public abstract class SystemPlatform {
    VideoFomat videoFomat;


    /**
     * 視訊播放
     */
     abstract void playVedio();

    public void setVideoFomat(VideoFomat videoFomat) {
        this.videoFomat = videoFomat;
    }
}
package Bridge;

/**
 * <p>ClassName      AVIFormat
 * <p>Description
 * <p>Author         ChongLou
 * <p>Version
 * <p>Date           2017/11/27 0:27
 */
public class AVIFormat implements VideoFomat {
    public void decodingAndPlay() {
        System.out.println("AVI video");
    }
}
package Bridge;

/**
 * <p>ClassName      MPEGFormat
 * <p>Description
 * <p>Author         ChongLou
 * <p>Version
 * <p>Date           2017/11/27 0:26
 */
public class MPEGFormat implements VideoFomat {
    public void decodingAndPlay() {
        System.out.println( " MPEG video" );
    }
}
package Bridge;

/**
 * <p>ClassName      WindowsPlatform
 * <p>Description
 * <p>Author         ChongLou
 * <p>Version
 * <p>Date           2017/11/27 0:21
 */
public class WindowsPlatform extends SystemPlatform {

    void playVedio() {
        System.out.print("windows play ");
        videoFomat.decodingAndPlay();
    }
}
package Bridge;

/**
 * <p>ClassName      MacPlatform
 * <p>Description
 * <p>Author         ChongLou
 * <p>Version
 * <p>Date           2017/11/27 0:37
 */
public class MacPlatform extends SystemPlatform {

    void playVedio() {
        System.out.print("mac play ");
        videoFomat.decodingAndPlay();
    }
}
package Bridge;

/**
 * <p>ClassName      Client
 * <p>Description
 * <p>Author         ChongLou
 * <p>Version
 * <p>Date           2017/11/27 0:44
 */
public class Client {
    public static void main(String[] args) {

        // 使用Mac播放AVI
        VideoFomat videoFomat1 = new AVIFormat();
        SystemPlatform systemPlatform1 = new MacPlatform();
        systemPlatform1.setVideoFomat( videoFomat1 );
        systemPlatform1.playVedio();

        // 使用windos 播放MPEG
        VideoFomat videoFomat2 = new MPEGFormat();
        SystemPlatform systemPlatform2 = new WindowsPlatform();
        systemPlatform2.setVideoFomat( videoFomat2 );
        systemPlatform2.playVedio();


    }

}

結果

這裡寫圖片描述

總結

暫無