設想如果要繪製矩形、圓形、橢圓、正方形,我們至少需要4個形狀類,但是如果繪製的圖形需要具有不同的顏色,如紅色、綠色、藍色等,此時至少有如下兩種設計方案:
第一種方案是爲每一種形狀都提供一套各種顏色的版本
第二種方案是根據實際的需要對形狀和顏色進行組合
對於有兩個變化維度(即兩個變化的原因)的系統,採用方案二來進行設計系統中類的個數更少,且系統擴展更爲方便。設計方案二即是橋接模式的應用。橋接模式將繼承關係轉換爲關聯關係,從而降低了類與類之間的耦合,減少了代碼編寫量。
模式的定義
橋接模式(Bridge Pattern):將抽象部分與它的實現部分分離,使它們都可以獨立地變化。它是一種對象結構型模式,又稱爲柄體(Handle and Body)模式或接口(Interface)模式。
模式的類圖
橋接模式的代碼說明
抽象部分:
public abstract class Shape {
private ShapeColor shapeColor;
public Shape(ShapeColor color) {
this.shapeColor = color;
}
public abstract String getShapeName();
@Override
public String toString() {
return "我的形狀是:" +this.getShapeName() + ", 我的顏色是:" + this.shapeColor.getColor();
}
}
public class Cycle extends Shape {
public Cycle(ShapeColor color) {
super(color);
}
@Override
public String getShapeName() {
return "圓形";
}
}
public class Square extends Shape {
public Square(ShapeColor color) {
super(color);
}
@Override
public String getShapeName() {
return "正方形";
}
}
public class Triangle extends Shape {
public Triangle(ShapeColor color) {
super(color);
}
@Override
public String getShapeName() {
return "三角形";
}
}
實現部分:
public abstract class ShapeColor {
public abstract String getColor();
}
public class Bule extends ShapeColor {
@Override
public String getColor() {
return "藍色";
}
}
public class Red extends ShapeColor {
@Override
public String getColor() {
return "紅色";
}
}
public class Yellow extends ShapeColor {
@Override
public String getColor() {
return "黃色";
}
}
客戶端:
public class Client {
public static void main(String[] args) {
ShapeColor yellow = new Yellow();
ShapeColor red = new Red();
Shape yellowCycle = new Cycle(yellow);
Shape redCycle = new Cycle(red);
Shape yellowSquire = new Square(yellow);
Shape redSquire = new Square(red);
System.out.println(yellowCycle);
System.out.println(redCycle);
System.out.println(yellowSquire);
System.out.println(redSquire);
}
}
抽象部分的類繼承體系,頂層是Shape抽象類,Shape的實現類可以有很多,圓形,三角形,正方形,菱形,還可以隨意擴展出來非常多的形狀
實現部分的類繼承體系表示的是Shape的顏色,可有多重顏色,根據自己的需要,還可以擴展出來更多的顏色
抽象部分和實現部分兩者是可以獨立擴展的,兩者之間的關係是組合的關係,實現部分作爲一個屬性,集成到抽象部分的類中去,這是兩個體系發生聯繫的地方,表現在類圖上,就是兩個互相獨立演化的部分,中間用一條線連起來,這條線看起來就像是一座橋,這個模式就叫做橋接模式
應用的場景
系統有兩個獨立的變化維度,而這兩個維度都需要進行擴展
想要防止因爲多層次的繼承導致類數量的膨脹
抽象化角色和實現化角色可以以繼承的方式獨立擴展而互不影響,在程序運行時可以動態將一個抽象化子類的對象和一個實現化子類的對象進行組合,即系統需要對抽象化角色和實現化角色進行動態耦合