橋接模式(Bridge Pattern)——處理多維度變化
前言
P: 嘿,小重樓!我們這邊有個簡單的需求,交個你了。
me: 啥需求?我拒絕!!!
P: 呀?你小子敢拒絕老孃的需求,活膩了吧?
me: 好吧,我接。。。做啥呢?我接。。。
P: 我這邊需要開發一個視訊播放器。不僅要跨平臺(Linux,Mac,Windows等)還要支援播放多種格式的視訊檔案(MPEG,RMVB,AVI,WMI等)哦。
me:這。。。這個要求有點太高了吧?還好現在開源專案多,可以解決技術問題。但是,這個該怎麼設計呢???
Master: 沒關係。。。我給你一個法寶,保準輕鬆解決設計問題。諾。。。橋接模式,拿去,隨便用!
概述
橋接模式(Bridge Pattern)
如果軟體系統中某個類存在兩個獨立變化的維度,通過該模式可以將這兩個維度分離出來,使兩者可以獨立擴充套件,讓系統更加符合“單一職責原則”。與多層繼承方案不同,它將兩個獨立變化的維度設計為兩個獨立的繼承等級結構,並且在抽象層建立一個抽象關聯,該關聯關係類似一條連線兩個獨立繼承結構的橋,故名橋接模式。
類圖
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();
}
}
結果
總結
暫無