適配器模式(Adapter)

1.簡述

適配器模式就是將一個類的接口變成客戶端所期待的另一種接口,從而使原本因接口不匹配而無法在一起工作的兩個類能夠在一起工作。下面這個例子很好的說明了適配器的作用


2.角色

  •  目標角色(Target):客戶所期待的接口。目標可以是具體的或抽象的類,也可以是接口。
  • 源角色(Adaptee)也就是被適配的類:需要適配的類或適配者類。
  • 適配器角色(Adapter):通過包裝一個需要適配的對象,把原接口轉換成目標接口。

3.兩種實現方式和UML類圖

(1).類的適配器模式(採用繼承實現)

 

(2).對象適配器(採用對象組合方式實現)

4.通用代碼

(1).類適配器通用代碼:

/*
 *	目標角色
 */
interface Target {
	// 目標角色有自己的方法
	public void request();
}

/*
 * 目標角色的實現類
 */
class ConcreteTarget implements Target {

	public void request() {
		System.out.println("我是目標角色的業務邏輯");
	}
}

/*
 * 源角色
 */
class Adaptee {
	// 原有的業務邏輯
	public void doSomething() {
		System.out.println("我是被適配角色的業務邏輯");
	}
}

/*
 * 適配器角色
 */
class Adapter extends Adaptee implements Target {
	public void request() {
		super.doSomething();
	}
}

public class Client {
	public static void main(String[] args) {
		// 如果要使用原有的業務邏輯
		Target target = new ConcreteTarget();
		target.request();
		// 現在增加了適配器角色後的業務邏輯
		Target target1 = new Adapter();
		target1.request();
	}
}

上面這種實現的適配器稱爲類適配器,因爲 Adapter 類既繼承了 Adaptee (被適配類),也實現了 Target 接口(因爲 Java 不支持多繼承,所以這樣來實現),在 Client 類中我們可以根據需要選擇並創建任一種符合需求的子類,來實現具體功能。另外一種適配器模式是對象適配器,它不是使用多繼承或繼承再實現的方式,而是使用直接關聯,或者稱爲委託的方式。我們來看下對象適配器的通用代碼。

(2).對象適配器通用代碼:

/*
 *	目標角色
 */
interface Target {
	// 目標角色有自己的方法
	public void request();
}

/*
 * 目標角色的實現類
 */
class ConcreteTarget implements Target {

	public void request() {
		System.out.println("我是目標角色的業務邏輯");
	}
}

/*
 * 源角色
 */
class Adaptee {
	// 原有的業務邏輯
	public void doSomething() {
		System.out.println("我是被適配角色的業務邏輯");
	}
}

//適配器類,直接關聯被適配類,同時實現標準接口
class Adapter implements Target {
	// 直接關聯被適配類
	private Adaptee adaptee;

	// 可以通過構造函數傳入具體需要適配的被適配類對象
	public Adapter(Adaptee adaptee) {
		this.adaptee = adaptee;
	}

	public void request() {
		// 這裏是使用委託的方式完成特殊功能
		this.adaptee.doSomething();
	}
}

//測試類
public class Client {
	public static void main(String[] args) {
		// 使用普通功能類
		Target concreteTarget = new ConcreteTarget();
		concreteTarget.request();

		// 使用特殊功能類,即適配類,
		// 需要先創建一個被適配類的對象作爲參數
		Target adapter = new Adapter(new Adaptee());
		adapter.request();
	}
}

測試結果與上面的一致。從類圖中我們也知道需要修改的只不過就是 Adapter 類的內部結構,即 Adapter 自身必須先擁有一個被適配類的對象,再把具體的特殊功能委託給這個對象來實現。使用對象適配器模式,可以使得 Adapter 類(適配類)根據傳入的 Adaptee 對象達到適配多個不同被適配類的功能,當然,此時我們可以爲多個被適配類提取出一個接口或抽象類。這樣看起來的話,似乎對象適配器模式更加靈活一點。

5.優點

  • 通過適配器,客戶端可以調用同一接口,因而對客戶端來說是透明的。這樣做更簡單、更直接、更緊湊。
  • 複用了現存的類,解決了現存類和複用環境要求不一致的問題。
  • 將目標類和適配者類解耦,通過引入一個適配器類重用現有的適配者類,而無需修改原有代碼。
  • 一個對象適配器可以把多個不同的適配者類適配到同一個目標,也就是說,同一個適配器可以把適配者類和它的子類都適配到目標接口。
  • 靈活性好。如果某一天突然不想要適配器了,沒問題,直接刪除這個適配器就可以了,其他代碼都不用修改。基本上就類似於一個靈活的構件,想用就用,不想用就卸載。

6.缺點

  • 類適配器的缺點:對於java、C#等不支持多重繼承的語言,一次最多隻能適配一個適配者類,而且目標抽象類只能爲接口,不能爲類,其使用有一定的侷限性,不能將一個適配者類和他的子類同時適配到目標接口
  • 對象適配器的缺點:與類適配器模式相比,要想置換適配者類的方法就不容易。

7.適用場景

  • 想要複用一個已經存在的類,但是它卻不符合現有的接口規範,導致無法直接去訪問,這時創建一個適配器就能間接去訪問這個類中的方法。
  • 我們有一個類,想將其設計爲可重用的類(可被多處訪問),我們可以創建適配器來將這個類來適配其他沒有提供合適接口的類。
  • 使用第三方組件,組件接口定義和自己定義的不同,不希望修改自己的接口,但是要使用第三方組件接口的功能。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章