Java設(shè)計(jì)模式 -- 橋接模式
什么是橋接模式
橋接模式是一種結(jié)構(gòu)型設(shè)計(jì)模式,也被稱為“Handle/Body”。這種設(shè)計(jì)模式主要用于將抽象部分與它的實(shí)現(xiàn)部分分離,使它們可以獨(dú)立地變化。這種方式有助于減少系統(tǒng)中的耦合性,增加了擴(kuò)展性。
主要解決什么問題
橋接模式主要解決的是類的維度擴(kuò)展問題。在一個(gè)多維度變化的類中,使用繼承方式會(huì)導(dǎo)致類的數(shù)量急劇增加,而且增加新的維度也相對(duì)困難。而橋接模式能夠?qū)㈩惖母鱾€(gè)維度進(jìn)行分離,獨(dú)立擴(kuò)展,降低類之間的耦合度。
在什么時(shí)候我們需要使用橋接模式
當(dāng)你想要避免永久性地綁定某個(gè)抽象類與其實(shí)現(xiàn)時(shí)。
當(dāng)類的抽象和實(shí)現(xiàn)都應(yīng)該可以通過生成子類來擴(kuò)展時(shí)。
當(dāng)一個(gè)類的變化應(yīng)該不依賴于它的實(shí)現(xiàn)變化,兩者可以獨(dú)立變化時(shí)。
生活中的應(yīng)用實(shí)例
想象一下,你正在設(shè)計(jì)一個(gè)跨平臺(tái)的視頻播放器,支持Windows、Linux、Mac等多個(gè)操作系統(tǒng),同時(shí)需要支持多種不同的視頻格式,如MP4、AVI、MOV等。
如果使用繼承來設(shè)計(jì),那么需要為每個(gè)操作系統(tǒng)和視頻格式的組合創(chuàng)建一個(gè)子類(例如:WindowsMP4Player、LinuxAVIPlayer等)。隨著支持的操作系統(tǒng)和視頻格式的增加,子類的數(shù)量會(huì)急劇增加。
如果采用橋接模式,可以將操作系統(tǒng)(抽象化)和視頻格式(實(shí)現(xiàn)化)分離開來,分別擴(kuò)展。這樣只需要?jiǎng)?chuàng)建對(duì)應(yīng)操作系統(tǒng)和視頻格式的類,通過組合就可以得到我們想要的功能,大大減少了類的數(shù)量。
優(yōu)點(diǎn)
分離抽象接口及其實(shí)現(xiàn)部分。
提高了系統(tǒng)的可擴(kuò)展性,在兩個(gè)方向上都可以獨(dú)立擴(kuò)展。
實(shí)現(xiàn)細(xì)節(jié)對(duì)客戶透明,可以對(duì)用戶隱藏實(shí)現(xiàn)細(xì)節(jié)。
缺點(diǎn)
增加了系統(tǒng)的理解和設(shè)計(jì)難度,需要理解如何分離抽象和實(shí)現(xiàn)。
需要正確識(shí)別出系統(tǒng)中兩個(gè)獨(dú)立變化的維度。
使用場(chǎng)景
當(dāng)一個(gè)類存在兩個(gè)獨(dú)立變化的維度,且這兩個(gè)維度都需要進(jìn)行擴(kuò)展時(shí)。
當(dāng)你希望在不影響客戶端代碼的情況下隱藏抽象的實(shí)現(xiàn)細(xì)節(jié)時(shí)。
代碼示例
````
// 抽象化角色:顏色
interface Color {
? ? void bepaint(String shape);
}
// 實(shí)現(xiàn)化角色:紅色
class RedColor implements Color {
? ? public void bepaint(String shape){
? ? ? ? System.out.println("紅色的" + shape);
? ? }
}
// 實(shí)現(xiàn)化角色:藍(lán)色
class BlueColor implements Color {
? ? public void bepaint(String shape){
? ? ? ? System.out.println("藍(lán)色的" + shape);
? ? }
}
// 抽象化角色:形狀
abstract class Shape {
? ? protected Color color;
? ? public Shape(Color color) {
? ? ? ? this.color = color;
? ? }
? ? public abstract void draw();
}
// 擴(kuò)充抽象化角色:圓形
class Circle extends Shape {
? ? public Circle(Color color) {
? ? ? ? super(color);
? ? }
? ? public void draw() {
? ? ? ? color.bepaint("圓形");
? ? }
}
// 擴(kuò)充抽象化角色:正方形
class Square extends Shape {
? ? public Square(Color color) {
? ? ? ? super(color);
? ? }
? ? public void draw() {
? ? ? ? color.bepaint("正方形");
? ? }
}
public class Client {
? ? public static void main(String[] args) {
? ? ? ? Color red = new RedColor();
? ? ? ? Shape square = new Square(red);
? ? ? ? square.draw();
? ? ? ? Color blue = new BlueColor();
? ? ? ? Shape circle = new Circle(blue);
? ? ? ? circle.draw();
? ? }
}
````
在這個(gè)示例中,Color
?是實(shí)現(xiàn)化角色,RedColor
?和?BlueColor
?是具體實(shí)現(xiàn)化角色;Shape
?是抽象化角色,Square
?和?Circle
?是擴(kuò)充抽象化角色。Shape
?中包含了一個(gè)?Color
?的引用,形成了橋接。
當(dāng)我們運(yùn)行?main
?方法,就可以看到輸出 "紅色的正方形" 和 "藍(lán)色的圓形"