小白設計模式:橋接模式

定義

將抽象部分與實現部分分離開來,使得兩者能夠獨立變化,互不影響的結構型設計模式。設計模式

主要組成

抽象部分(Abstraction) : 該類保持一個對實現部分的引用,抽象部分中的方法須要調用實現部分的對象的方法來實現;這部分通常爲抽象類居多。bash

具體抽象部分(Concrete Abstraction):
抽象部分的具體實現,通常用於抽象部分方法的完善和擴展;框架

實現部分(Implementor) : 能夠爲接口或抽象類,其方法不必定要與抽象部分中的一致,通常狀況下是由實現部分提供基本的操做,而抽象部分定義的則是基於實現部分這些基本操做的業務方法;ide

具體實現部分(Concrete Implementor): 實現完善"實現部分"定義的相關接口功能;this

客戶端(Client): 客戶類,客戶端程序 (調用程序的地方)spa

具體例子

實現部分(Implementor) : Line"線",抽象爲接口類,方法爲Draw"畫線"。設計

具體實現部分(Concrete Implementor): 實現Line功能的子類,例如SolidLine繪製實線、DottedLine繪製虛線。code

抽象部分(Abstraction): 形狀Shape,持有一個Implementor的引用,並定義出須要藉助Implementor來實現的方法,好比使用「線"繪製出形狀cdn

具體抽象部分(Concrete Abstraction): Abstraction的實現類,完善擴展Implementor的方法。好比三角形、矩形、圓形等,繪製出各自的圖形對象

能夠看到Implementor和Abstraction有相對明顯的上下級,Abstraction須要調用Implementor來實現目的,是Implementor上級。

UML圖

框架代碼

實現部分(Implementor):

public interface Line {
	void draw();
}
複製代碼

具體實現部分(Concrete Implementor):

public class SolidLine implements Line {

	@Override
	public void draw() {
		//...
		System.out.println("繪製實線");
	}
}
複製代碼
public class GottedLine implements Line {

	@Override
	public void draw() {
		//...
		System.out.println("繪製虛線");
	}
}
複製代碼

抽象部分(Abstraction):

public abstract class Shape {
	//持有一個實現部分Implementor引用
	Line line;
	
	public Shape(Line line) {
		this.line = line;
	}
	
	public abstract void drawShape();
}
複製代碼

具體抽象部分(Concrete Abstraction):

public class Circular extends Shape {

	public Circular(Line line) {
		super(line);
	}

	@Override
	public void drawShape() {
		//...
		line.draw();
		System.out.println("繪製出圓形");
		//...
	}

}
複製代碼
public class Rectangle extends Shape {

	public Rectangle(Line line) {
		super(line);
	}

	@Override
	public void drawShape() {
		//...
		line.draw();
		System.out.println("繪製出矩形");
		//...
	}

}
複製代碼

客戶端調用示例:

//使用實線繪製圓形
		Circular solidCircular = new Circular(new SolidLine());
		solidCircular.drawShape();
		//使用虛線繪製圓形
		Circular gottedCircular = new Circular(new GottedLine());
		gottedCircular.drawShape();
		
		//使用實線繪製矩形
		Rectangle solidRectangle = new Rectangle(new SolidLine());
		solidRectangle.drawShape();
		//使用虛線繪製矩形
		Rectangle gottedRectangle = new Rectangle(new GottedLine());
		gottedRectangle.drawShape();
複製代碼

假設不使用橋接模式

上述例子假設沒使用橋接模式,很明顯會出現"類爆炸"的問題,類數量出現快速增長:

假設目前只有m=3種線: 實線、虛線、雙實線,須要繪製的形狀爲n=2種:圓形、矩形。

那麼當實現的類個數爲m * n ,之後不管多增長一種形狀(增長m個線數量的實現類),或者多增長一種線(增長n個形狀的實現類),(在基數足夠大的狀況下)都會爆炸式的增長太多的實現類。

而若是如上使用橋接模式,不管是增長形狀(抽象部分)、線(實現部分),理論上都只須要增長各自的一個具體實現,實現了抽象部分和實現部分能夠獨立修改互不影響。

總結

橋接模式通常用於存在上下級關係的二維變化系統中,將底層的部分分割爲實現層,將較上層的部分分割爲抽象層。 抽象層中的方法實現實際依賴於實現層對象的方法。

優勢

分離抽象和實現部分: 橋接模式分離了抽象和實現部分,從而極大地提升了系統的靈活性。讓抽象部分和實現部分獨立開來,分別定義接口,這有助於對系統進行分層,從而產生更好的結構化的系統。對於系統的高層部分,只須要知道抽象部分和實現部分的接口就能夠了。

靈活的擴展性: 因爲橋接模式把抽象和實現部分分離開了,並且分別定義接口,這就使得抽象部分和實現部分能夠分別獨立的擴展,而不會相互影響,從而大大的提升了系統的可擴展性。可動態切換實現。 因爲橋接模式把抽象和實現部分分離開了,那麼在實現橋接的時候,就能夠實現動態的選擇和使用具體的實現,也就是說一個實現再也不是固定的綁定在一個抽象接口上了,能夠實現運行期間動態的切換實現。

缺點

實際應用中相對不容易設計,由於判斷哪部分做爲實現部分,哪部分做爲抽象部分對開發者要有必定的經驗要求。

使用場景

若是一個系統須要在構件的抽象化角色和具體化角色之間增長更多的靈活性,避免在兩個層次之間創建靜態的繼承關係,能夠經過橋接模式使他們在抽象層創建一個關聯關係。 對於那些不但願使用繼承或由於多層次繼承致使系統類的個數急劇增長的系統,也能夠考慮使用橋接模式。 一個類存在兩個獨立變化的維度,且這兩個維度都須要進行擴展。

思考:

1.橋接模式能夠作到的感受裝飾者模式好像也能夠作到,兩者的區別?

裝飾者模式支持使用多個裝飾者屢次裝飾被裝飾者,而且要求裝飾者和被裝飾者提供一致的接口行爲,接口要求返回的也是統一的被裝飾者接口對象。 而橋接模式通常用一個抽象部分來擴展完善實現部分,並不要求提供一致的接口行爲。

裝飾者模式通常沒有明顯的上下級依賴關係,可是橋接模式的2個維度每每會有上下級依賴關係的存在。

2.怎麼判斷哪部分做爲實現部分,哪部分做爲抽象部分?

通常是真正的"實現"部分(被依賴的部分)做爲實現部分,上層做爲抽象部分,能夠從例子中理會,由於要繪製形狀須要依賴於繪製線,繪製線實際上是真正的實現部分,繪製形狀只是把繪製的線進行拼接(擴展完善了線的功能做用,封裝業務功能等)。因此線是實現部分,形狀是抽象部分。

公衆號

相關文章
相關標籤/搜索