橋接模式
定義
將抽象部分與實現(行爲)部分分離,使他們都可以獨立的變化。橋接模式的做法是把變化部分(實現)抽象出來,是變化部分與主類(抽象)分離開來,
從而將多個維度的變化徹底分離。最後,提供一個管理類來組合不同維度上的變化,通過這種組合來滿足業務的需要。
具體案例
本案例是實現汽車安裝引擎的功能汽車有兩種 奔馳和寶馬 他們安裝的引擎不同 怎麼實現?
有兩種方法
1.傳統方法
public interface Car{ public void installEngine200(); public void installEngine300(); }
public class Benz implements Car{ @Override public void installEngine200(){ System.out.println("Benz車組裝Engine200"); } @Override public void installEngine300(){ System.out.println("Benz車組裝Engine300"); } }
public class Bwm implements Car{ @Override public void installEngine200(){ System.out.println("Bwm車組裝Engine200"); } @Override public void installEngine300(){ System.out.println("Benz車組裝Engine300"); } }
public class Client { public static void main(String[] args) { //奔馳車安裝200引擎 Car benz=new Benz(); benz.installEngine200(); //寶馬車安裝300引擎 Car bwm=new Bwm(); bwm.installEngine300(); } }
缺點:只要在Car接口中增加一個引擎類型的方法,那麼它的具體實現類中也得增加一個空實現(如果該車不需要這個引擎),比如再增加一個型號400的引擎
相應的奔馳和寶馬中都得增加該方法 但是我奔馳車不需要這種引擎 這樣造成了代碼的冗餘 所以這種方法不好擴展,這就要用第二種方法:橋接模式
2.使用橋接模式
//Implementor : Engine 定義實現接口(也就是引擎接口)。//與實現(行爲)部分
public interface Engine { public void addEngine(); }
//ConcreteImplementor : Engine200 ;Engine300 實現 引擎接口中方法。
//具體實現接口
public class Engine200 implements Engine { @Override public void addEngine() { System.out.println("組裝Engine200"); } }
public class Engine300 implements Engine { @Override public void addEngine() { System.out.println("組裝Engine300"); } }
//Abstraction : Car 定義抽象接口。
//抽象部分
public abstract class Car { private Engine engine;// 持有一個實現部分對象,形成聚合關係 public Car(Engine engine) { this.engine = engine; } public Engine getEngine() { return engine; } public void setEngine(Engine engine) { this.engine = engine; } public abstract void install(); }
//RefinedAbstraction :Benz ;Bwm 擴展 Abstraction 類。
public class Benz extends Car { public Benz(Engine engine) { super(engine); } @Override public void install() { System.out.println("Benz車安裝"); this.getEngine().addEngine(); } }
public class Bwm extends Car { public Bwm(Engine engine) { super(engine); } @Override public void install() { System.out.println("Bwm車安裝"); this.getEngine().addEngine(); } }
//測試代碼
public static void main(String[] args) { //創建實現(行爲) ->Engine引擎 //第一種 引擎 Engine engine200=new Engine200(); //第二種 引擎 Engine engine300=new Engine300(); //創建抽象 ->車 Car benz=new Benz(engine200); benz.install(); Car bwm=new Bwm(engine300); bwm.install(); } }
運行結果:
Benz車安裝組裝Engine200
Bwm車安裝
組裝Engine300
應用場景
1.如果不希望在抽象和實現部分採用固定的綁定關係,可以採用橋接模式,來把抽象和實現部分分開,然後在程序運行期間來動態的設置抽象部分需要用到的具體實現,還可以動態切換具體的實現。2.如果出現抽象部分和實現部分都應該可以擴展的情況,可以採用橋接模式,讓抽象部分和實現部分可以獨立的變化,從而可以靈活的進行單獨擴展,而不是攪在一起,擴展一邊回影響另一邊。
3.如果希望實現部分的修改,不會對客戶產生影響,可以採用橋接模式,客戶是面向對象的接口在運行,實現部分的修改
3、如果希望實現部分的修改,不會對客戶產生影響,可以採用橋接模式,客戶是面向抽象的接口在運行,實現部分的修改,可以獨立於抽象部分,也就不會對客戶產生影響了,也可以說對客戶是透明的。
4、如果採用繼承的實現方案,會導致產生很多子類,對於這種情況,可以考慮採用橋接模式,分析功能變化的原因,看看是否能分離成不同的緯度,然後通過橋接模式來分離它們,從而減少子類的數目。