適配器模式(Adapter):類適配器、對象適配器

適配器模式(Adapter):將一個類的接口轉換成客戶但願的另一個接口。A d a p t e r 模式使得本來因爲接口不兼容而不能一塊兒工做的那些類能夠一塊兒工做。ide

適用場景:函數

一、已經存在的類的接口不符合咱們的需求;測試

二、建立一個能夠複用的類,使得該類能夠與其餘不相關的類或不可預見的類(即那些接口可能不必定兼容的類)協同工做;this

三、在不對每個都進行子類化以匹配它們的接口的狀況下,使用一些已經存在的子類。spa

通用類圖:設計

 

咱們生活中經常聽到的是代理

電源適配器,它是用於電流變換(整流)的設備。適配器的存在,就是爲了將已存在的東西(接口)轉換成適合咱們的須要、能被咱們所利用。在現實生活中,適配器更多的是做爲一個中間層來實現這種轉換做用。對象

在上面的通用類圖中,Cient 類最終面對的是 Target 接口(或抽象類),它只可以使用符合這一目標標準的子類;而 Adaptee 類則是被適配的對象(也稱 源角色),由於它包含specific (特殊的)操做、功能等,因此咱們想要在本身的系統中使用它,將其轉換成符合咱們標準的類,使得 Client 類能夠在透明的狀況下任意選擇使用 ConcreteTarget 類或是具備特殊功能的 Adatee 類。blog

代碼實現以下:繼承

// 已存在的、具備特殊功能、但不符合咱們既有的標準接口的類
class Adaptee {
	public void specificRequest() {
		System.out.println("被適配類具備 特殊功能...");
	}
}


// 目標接口,或稱爲標準接口
interface Target {
	public void request();
}

// 具體目標類,只提供普通功能
class ConcreteTarget implements Target {
	public void request() {
		System.out.println("普通類 具備 普通功能...");
	}
}

 

// 適配器類,繼承了被適配類,同時實現標準接口
class Adapter extends Adaptee implements Target{
	public void request() {
		super.specificRequest();
	}
}

 

// 測試類
public class Client {
	public static void main(String[] args) {
		// 使用普通功能類
		Target concreteTarget = new ConcreteTarget();
		concreteTarget.request();
		
		// 使用特殊功能類,即適配類
		Target adapter = new Adapter();
		adapter.request();
	}
}

 測試結果:

普通類 具備 普通功能...
被適配類具備 特殊功能...

 上面這種實現的適配器稱爲類適配器,由於 Adapter 類既繼承了 Adaptee (被適配類),也實現了 Target 接口(由於 Java 不支持多繼承,因此這樣來實現),在 Client 類中咱們能夠根據須要選擇並建立任一種符合需求的子類,來實現具體功能。

另一種適配器模式是對象適配器,它不是使用多繼承或繼承再實現的方式,而是使用直接關聯,或者稱爲委託的方式,類圖以下:

 

代碼實現以下:

// 適配器類,直接關聯被適配類,同時實現標準接口
class Adapter implements Target{
	// 直接關聯被適配類
	private Adaptee adaptee;
	
	// 能夠經過構造函數傳入具體須要適配的被適配類對象
	public Adapter (Adaptee adaptee) {
		this.adaptee = adaptee;
	}
	
	public void request() {
		// 這裏是使用委託的方式完成特殊功能
		this.adaptee.specificRequest();
	}
}


// 測試類
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 對象達到適配多個不一樣被適配類的功能,固然,此時咱們能夠爲多個被適配類提取出一個接口或抽象類。這樣看起來的話,彷佛對象適配器模式更加靈活一點。

小結:

一、適配器模式也是一種包裝模式,與以前的 Decorator 裝飾模式一樣具備包裝的功能;此外,對象適配器模式還具備顯式委託的意思在裏面(其實類適配器也有這種意思,只不過比較隱含而已),那麼我在認爲它與 Proxy 代理模式也有點相似;

二、從上面一點對比來看, Decorator 、 Proxy、 Adapter 在實現了自身的最主要目的(這個得看各個模式的最初動機、描述)以外,都能夠在包裝的先後進行額外的、特殊的功能上的增減,由於我認爲它們都有委託的實現意思在裏面;

三、我所看的書中說適配器模式不適合在詳細設計階段使用它,它是一種補償模式,專用來在系統後期擴展、修改時所用。

個人相關文章:

裝飾模式(Decorator)與動態代理的強強聯合http://haolloyin.blog.51cto.com/1177454/338671

(Dynamic Proxy)動態代理模式的Java實現http://haolloyin.blog.51cto.com/1177454/333257

(Proxy)代理模式的Java實現http://haolloyin.blog.51cto.com/1177454/333189

相關文章
相關標籤/搜索