Java設(shè)計(jì)模式-橋接模式
簡介
橋接模式(Bridge Pattern)是一種結(jié)構(gòu)性設(shè)計(jì)模式,它的主要作用是將抽象部分和實(shí)現(xiàn)部分解耦,使它們可以獨(dú)立變化而不會互相影響。橋接模式最早由GoF(Gang of Four)提出,在《設(shè)計(jì)模式》一書中有詳細(xì)的介紹。
橋接模式和其他設(shè)計(jì)模式的區(qū)別在于它關(guān)注的是如何將抽象和實(shí)現(xiàn)分離,從而達(dá)到靈活性和可擴(kuò)展性的目的。與之相比,適配器模式關(guān)注的是如何將不兼容的接口轉(zhuǎn)換成可兼容的接口,裝飾者模式關(guān)注的是如何動態(tài)地為對象添加行為,而組合模式則是將對象組合成樹形結(jié)構(gòu),以表示“部分-整體”的層次結(jié)構(gòu)。
實(shí)現(xiàn)
假設(shè)我們正在構(gòu)建一個圖形用戶界面(GUI)框架,我們需要支持多個操作系統(tǒng)和窗口管理器。我們可以使用橋接模式來實(shí)現(xiàn)這個功能。我們可以將操作系統(tǒng)和窗口管理器的實(shí)現(xiàn)分開,以便它們可以獨(dú)立地變化。我們可以定義一個抽象的Window類,它有一個實(shí)現(xiàn)了WindowImpl接口的實(shí)例變量。WindowImpl接口表示窗口管理器的實(shí)現(xiàn)。我們可以定義一個操作系統(tǒng)的抽象類,它有一個實(shí)現(xiàn)了OsImpl接口的實(shí)例變量。OsImpl接口表示操作系統(tǒng)的實(shí)現(xiàn)。
下面是一個示例代碼:
interface WindowImpl {
? ?void draw(int x, int y, int width, int height, String color);
}
class LinuxWindowImpl implements WindowImpl {
? ?public void draw(int x, int y, int width, int height, String color) {
? ? ? ?System.out.println("Drawing a Linux window at (" + x + ", " + y + ") with width " + width + ", height "
? ? ? ? ? ? ? ? ? ? ? ? ? + height + ", and color " + color);
? ?}
}
class WindowsWindowImpl implements WindowImpl {
? ?public void draw(int x, int y, int width, int height, String color) {
? ? ? ?System.out.println("Drawing a Windows window at (" + x + ", " + y + ") with width " + width + ", height "
? ? ? ? ? ? ? ? ? ? ? ? ? + height + ", and color " + color);
? ?}
}
abstract class Window {
? ?private WindowImpl impl;
? ?
? ?public Window(WindowImpl impl) {
? ? ? ?this.impl = impl;
? ?}
? ?
? ?public void draw(int x, int y, int width, int height, String color) {
? ? ? ?impl.draw(x, y, width, height, color);
? ?}
}
abstract class Os {
? ?private WindowImpl impl;
? ?
? ?public Os(WindowImpl impl) {
? ? ? ?this.impl = impl;
? ?}
? ?public void drawWindow(int x, int y, int width, int height, String color) {
? ? Window window = createWindow(impl);
? ? window.draw(x, y, width, height, color);
? ?}
protected abstract Window createWindow(WindowImpl impl);
}
class LinuxOs extends Os {
public LinuxOs(WindowImpl impl) {
?super(impl);
}
? ?protected Window createWindow(WindowImpl impl) {
? ? return new LinuxWindow(impl);
}
}
class WindowsOs extends Os {
public WindowsOs(WindowImpl impl) {
?super(impl);
}
? ?protected Window createWindow(WindowImpl impl) {
? ? return new WindowsWindow(impl);
}
}
class LinuxWindow extends Window {
public LinuxWindow(WindowImpl impl) {
?super(impl);
}
}
class WindowsWindow extends Window {
public WindowsWindow(WindowImpl impl) {
?super(impl);
}
}
在這個例子中,WindowImpl接口表示窗口管理器的實(shí)現(xiàn),LinuxWindowImpl和WindowsWindowImpl類分別是Linux和Windows操作系統(tǒng)的窗口管理器的實(shí)現(xiàn)。Window抽象類有一個實(shí)現(xiàn)了WindowImpl接口的實(shí)例變量,并且有一個draw方法,該方法將調(diào)用WindowImpl的draw方法。Os抽象類也有一個實(shí)現(xiàn)了WindowImpl接口的實(shí)例變量,并且有一個drawWindow方法,該方法將創(chuàng)建一個Window對象,并調(diào)用draw方法。LinuxOs和WindowsOs類分別是Linux和Windows操作系統(tǒng)的實(shí)現(xiàn),它們都是Os抽象類的子類。它們實(shí)現(xiàn)了createWindow方法,并返回一個具體的Window對象。
優(yōu)缺點(diǎn)
優(yōu)點(diǎn):
橋接模式可以將抽象部分和實(shí)現(xiàn)部分分離,使它們可以獨(dú)立變化,從而達(dá)到靈活性和可擴(kuò)展性的目的。
橋接模式可以讓客戶端代碼僅關(guān)注抽象部分,而不必關(guān)注實(shí)現(xiàn)部分的細(xì)節(jié)
橋接模式可以減少繼承的使用,因?yàn)槔^承是一種靜態(tài)的方式,而橋接模式則是一種動態(tài)的方式。
缺點(diǎn):
橋接模式需要增加額外的抽象和實(shí)現(xiàn)層次,從而增加系統(tǒng)的復(fù)雜度和理解難度。
橋接模式需要對系統(tǒng)進(jìn)行重新設(shè)計(jì),從而增加了開發(fā)的時間和成本。
運(yùn)用場景:
橋接模式適用于以下情況:
當(dāng)一個類存在兩個獨(dú)立變化的維度時,可以使用橋接模式來將它們解耦,從而使它們可以獨(dú)立變化。
當(dāng)一個類需要在運(yùn)行時切換不同的實(shí)現(xiàn)時,可以使用橋接模式來實(shí)現(xiàn)這一需求。
當(dāng)一個類的抽象和實(shí)現(xiàn)部分可以分別擴(kuò)展時,可以使用橋接模式來實(shí)現(xiàn)這一需求。