1.橋接模式是什麼
1.百度百科
橋接模式(Bridge pattern)是将抽象部分與它的實作部分分離,使它們都可以獨立地變化。它是一種對象結構型模式,又稱為柄體(Handle and Body)模式或接口(Interface)模式。
話說百度百科越來越不靠譜了
2.維基百科
The bridge pattern is a design pattern used in software engineering that is meant to "decouple an abstraction from its implementation so that the two can vary independently", introduced by the Gang of Four.[1] The bridge uses encapsulation, aggregation, and can use inheritance to separate responsibilities into different classes.
When a class varies often, the features of object-oriented programming become very useful because changes to a program's code can be made easily with minimal prior knowledge about the program. The bridge pattern is useful when both the class and what it does vary often. The class itself can be thought of as the abstraction and what the class can do as the implementation. The bridge pattern can also be thought of as two layers of abstraction.
When there is only one fixed implementation, this pattern is known as the Pimpl idiom in the C++ world.
The bridge pattern is often confused with the adapter pattern. In fact, the bridge pattern is often implemented using the object adapter pattern, e.g. in the Java code below.
Variant: The implementation can be decoupled even more by deferring the presence of the implementation to the point where the abstraction is utilized.**
3.lz了解
将現實化的對象用抽象化的中間層隔開。現實對象依賴接口,中間層也依賴接口。
以便于增加接口實作類而不影響項目整體架構。簡單來說就是用抽象類和接口将各個接口的實作類隔離開進而達到一種實作類和另外一種接口的實作類解除耦合而讓其各自變化的目的。
4.核心角色
抽象化(Abstraction)角色:抽象化給出的定義,并儲存一個對實作化對象的引用。
修正抽象化(Refined Abstraction)角色:擴充抽象化角色,改變和修正父類對抽象化的定義。
抽象實作化(Implementor)角色:這個角色給出實作化角色的接口,但不給出具體的實作。必須指出的是,這個接口不一定和抽象化角色的接口定義相同,實際上,這兩個接口可以非常不一樣。實作化角色應當隻給出底層操作,而抽象化角色應當隻給出基于底層操作的更高一層的操作。
具體實作化(Concrete Implementor)角色:這個角色給出實作化角色接口的具體實作。
2.橋接模式解決了什麼問題
抽象實作分離 分離抽象接口及其實作部分。提高了比繼承更好的解決方案。
降低實作更換難度 橋接模式提高了系統的可擴充性,在任意一個接口中任意擴充一個實作類,都不需要修改原有系統。
隐藏實作方式 實作細節對客戶透明,可以對使用者隐藏實作細節。
3.橋接模式用法
就拿乘坐鐵路來舉例子,鐵路一定有一個目的地和一個出發地。而這兩個地方是不斷變換的。下面我就示範怎麼動态切換起始地目地的方法。
首先是起始地、目的地的抽象角色就是上文中抽象現實化角色。
//起始站抽象
public interface Startinglace {
public void fromWhere();
}
//終點站抽象
public interface Endinglace {
public void toWhere();
}
具體實作化角色
//具體出發地
public class StartinglaceBeijing implements Startinglace {
@Override
public void fromWhere() {
System.out.println("從北京出發");
}
}
public class StartinglaceGuangzhou implements Startinglace {
@Override
public void fromWhere() {
System.out.println("從廣州出發");
}
}
public class StartinglaceShanghai implements Startinglace {
@Override
public void fromWhere() {
System.out.println("從上海出發");
}
}
//具體目的地
public class EndinglaceBeijin implements Endinglace {
@Override
public void toWhere() {
System.out.println("到達北京");
}
}
public class EndinglaceGuangzhou implements Endinglace {
@Override
public void toWhere() {
System.out.println("到達廣州");
}
}
public class EndinglaceShanghai implements Endinglace {
@Override
public void toWhere() {
System.out.println("到達上海");
}
}
火車站發車、抽象化角色
/**
* 鐵路
*/
public abstract class Railway {
//來源地
private Startinglace startinglace;
//目的地
private Endinglace endinglace;
public Railway(Startinglace startinglace, Endinglace endinglace) {
super();
this.startinglace = startinglace;
this.endinglace = endinglace;
}
//鐵路具體運作方式
public abstract void run();
public Startinglace getStartinglace() {
return startinglace;
}
public void setStartinglace(Startinglace startinglace) {
this.startinglace = startinglace;
}
public Endinglace getEndinglace() {
return endinglace;
}
public void setEndinglace(Endinglace endinglace) {
this.endinglace = endinglace;
}
}
具體鐵路的運作、修正抽象化角色
public class RailwayRuning extends Railway {
public RailwayRuning(Startinglace startinglace, Endinglace endinglace) {
super(startinglace, endinglace);
}
@Override
public void run() {
super.getStartinglace().fromWhere();;
super.getEndinglace().toWhere();;
}
}
用戶端的調用
public class Customer {
public static void main(String[] args) {
//從廣州到北京
StartinglaceGuangzhou startinglaceGuangzhou = new StartinglaceGuangzhou();
EndinglaceBeijin endinglaceBeijin = new EndinglaceBeijin();
RailwayRuning railwayRuning = new RailwayRuning(startinglaceGuangzhou,endinglaceBeijin);
railwayRuning.run();
//從上海到廣州
StartinglaceShanghai startinglaceShanghai = new StartinglaceShanghai();
EndinglaceGuangzhou endinglaceGuangzhou = new EndinglaceGuangzhou();
railwayRuning = new RailwayRuning(startinglaceShanghai,endinglaceGuangzhou);
//railwayRuning.run();
//突然有急事要去北京
railwayRuning.setEndinglace(endinglaceBeijin);
railwayRuning.run();
}
}
從上述例子中可以看出始發站和目的地都是可以随意拓展的隻需繼承各自的抽象化角色。目的地切換也非常容易,目的地和出發地完全依賴抽象化的角色。将實作用抽象類隔開進而達到解除耦合的目的。
4.橋接模式的問題
系統複雜度增加 橋接模式的引入會增加系統的了解與設計難度,由于聚合關聯關系建立在抽象層,要求開發者針對抽象進行設計與程式設計。
定位獨立次元困難 橋接模式要求正确識别出系統中兩個獨立變化的次元,是以其使用範圍具有一定的局限性。
5.橋接模式總結
使用場景:
- 如果一個系統需要在構件的抽象化角色和具體化角色之間增加更多的靈活性,避免在兩個層次之間建立靜态的繼承聯系,通過橋接模式可以使它們在抽象層建立一個關聯關系。
- 對于那些不希望使用繼承或因為多層次繼承導緻系統類的個數急劇增加的系統,橋接模式尤為适用。
- 一個類存在兩個獨立變化的次元,且這兩個次元都需要進行擴充。
設計模式缺點是增加系統的複雜性并讓系統難以了解。反反複複提示自己就是應為設計模式的濫用是一個非常可怕的事情,橋接模式的使用場景的中說了通過橋接模式在抽象層建立關聯關系。那麼這個關聯關系最好就是穩定的,如果這個關聯關系并不穩定那麼不适合使用橋接模式,而變化在實作的修改和拓展上。就像上面火車的例子從出發地到目的地這個結構是非常穩定的。那麼變化的僅僅是出發地和目的地的實作類不同。那麼動态切換出發目的地或者增加目的地都是很靈活的。
引用
https://www.cnblogs.com/chenssy/p/3317866.html