Java設(shè)計(jì)模式之-橋接模式
什么是橋接模式?
橋接模式(Bridge Pattern)是一種結(jié)構(gòu)型設(shè)計(jì)模式,其主要目標(biāo)是將抽象與實(shí)現(xiàn)解耦,使得兩者可以獨(dú)立地變化。在橋接模式中,我們有一個抽象類和一個實(shí)現(xiàn)類,抽象類依賴于實(shí)現(xiàn)類。這樣,如果我們想要改變實(shí)現(xiàn)或者抽象,我們可以獨(dú)立地做到這一點(diǎn)。
主要解決什么問題?
橋接模式主要解決的是類的維度爆炸問題。如果一個類有多個獨(dú)立變化的維度,那么不使用設(shè)計(jì)模式,我們可能需要為每一種可能的組合創(chuàng)建一個子類。這樣會導(dǎo)致子類數(shù)量大幅增加,且難以管理和維護(hù)。橋接模式通過將這些維度分離,并使它們各自獨(dú)立地變化,有效地解決了這個問題。
在什么時候我們需要使用橋接模式?
當(dāng)你需要避免永久的綁定抽象類和實(shí)現(xiàn)類時,或者兩個獨(dú)立變化的類時,你應(yīng)該使用橋接模式。此外,如果你希望在幾個類之間共享實(shí)現(xiàn),也應(yīng)該使用橋接模式。
生活中的應(yīng)用實(shí)例
想象一下你正在構(gòu)建一個跨平臺的圖形用戶界面框架。你有不同類型的元素,如按鈕、復(fù)選框等,而且你希望它們在所有主要操作系統(tǒng)(Windows、Linux、macOS)上工作。
你可以創(chuàng)建一個大的類層次結(jié)構(gòu)來覆蓋所有可能的組合,如 WindowsButton、LinuxButton 等等,但這樣做會導(dǎo)致類的數(shù)量爆炸,并且在添加新的操作系統(tǒng)或元素類型時,你需要修改所有類。橋接模式可以幫助你避免這個問題。
優(yōu)點(diǎn)
抽象和實(shí)現(xiàn)的分離:這是橋接模式的主要優(yōu)點(diǎn),它能使抽象和實(shí)現(xiàn)獨(dú)立地變化,增加或改變實(shí)現(xiàn)不會影響抽象類。
提高可擴(kuò)展性:你可以獨(dú)立地增加抽象和實(shí)現(xiàn)的類。
實(shí)現(xiàn)了細(xì)節(jié)對客戶端的隱藏:你可以對客戶隱藏實(shí)現(xiàn)的細(xì)節(jié)。
缺點(diǎn)
增加了系統(tǒng)的理解和設(shè)計(jì)難度:橋接模式將抽象和實(shí)現(xiàn)分離,這可能使理解和設(shè)計(jì)系統(tǒng)更加復(fù)雜。
需要正確識別出系統(tǒng)中兩個獨(dú)立變化的維度:識別出系統(tǒng)中的兩個獨(dú)立變化的維度需要對系統(tǒng)有深入的理解和分析。
使用場景
當(dāng)一個類存在兩個獨(dú)立變化的維度,并且這兩個維度都需要進(jìn)行擴(kuò)展時,我們可以使用橋接模式。
代碼示例
// 實(shí)現(xiàn)類接口
interface Implementor {
? ? void operationImpl();
}
// 具體實(shí)現(xiàn)類
class ConcreteImplementorA implements Implementor {
? ? public void operationImpl() {
? ? ? ? System.out.println("Concrete Implementor A");
? ? }
}
class ConcreteImplementorB implements Implementor {
? ? public void operationImpl() {
? ? ? ? System.out.println("Concrete Implementor B");
? ? }
}
// 抽象類
abstract class Abstraction {
? ? protected Implementor implementor;
? ? protected Abstraction(Implementor implementor) {
? ? ? ? this.implementor = implementor;
? ? }
? ? public abstract void operation();
}
// 擴(kuò)展抽象類
class RefinedAbstraction extends Abstraction {
? ? protected RefinedAbstraction(Implementor implementor) {
? ? ? ? super(implementor);
? ? }
? ? public void operation() {
? ? ? ? implementor.operationImpl();
? ? }
}
public class BridgePatternDemo{
? ? public static void main(String[] args) {
? ? ? ? Implementor implementorA = new ConcreteImplementorA();
? ? ? ? Abstraction abstractionA = new RefinedAbstraction(implementorA);
? ? ? ? abstractionA.operation();
? ? ? ? Implementor implementorB = new ConcreteImplementorB();
? ? ? ? Abstraction abstractionB = new RefinedAbstraction(implementorB);
? ? ? ? abstractionB.operation();
? ? }
}
在這個例子中,Abstraction 是抽象類,Implementor 是實(shí)現(xiàn)類接口。我們有兩個具體的實(shí)現(xiàn)類 ConcreteImplementorA 和 ConcreteImplementorB,以及一個擴(kuò)展抽象類 RefinedAbstraction。在 main 方法中,我們創(chuàng)建了兩個 RefinedAbstraction 的實(shí)例,一個使用 ConcreteImplementorA,另一個使用 ConcreteImplementorB。當(dāng)我們調(diào)用 operation 方法時,每個實(shí)例都會調(diào)用相應(yīng)的 operationImpl 方法。