設計模式(八):適配器模式

来源:http://www.cnblogs.com/jenkinschan/archive/2016/08/07/5746005.html
-Advertisement-
Play Games

一、概述 適配器模式將一個類的介面,轉換為客戶期望的另一個介面。適配器讓原本不相容的類可以合作無間 二、解決問題 從模式的定義中,我們看到適配器模式就是用來轉換介面,解決不相容問題的。想想我們現實生活中的適配器,最常用的就是手機充電器了,也叫做電源適配器,它把家用交流強電轉換為手機用的直流弱電。其中 ...


一、概述

  適配器模式將一個類的介面,轉換為客戶期望的另一個介面。適配器讓原本不相容的類可以合作無間

二、解決問題

  從模式的定義中,我們看到適配器模式就是用來轉換介面,解決不相容問題的。想想我們現實生活中的適配器,最常用的就是手機充電器了,也叫做電源適配器,它把家用交流強電轉換為手機用的直流弱電。其中交流電就是被適配者,充電器是適配器,手機是用電客戶。

三、結構類圖

  

四、成員角色

  客戶(Client):只能調用目標介面功能,不能直接使用被適配器,但可以通過適配器的介面轉換間接使用被適配器。

  目標介面(Target):客戶看到的介面,適配器必須實現該介面才能被客戶使用。

  適配器(Adapter):適配器把被適配者介面轉換為目標介面,提供給客戶使用。

  被適配者(Adaptee):被適配者介面與目標介面不相容,需要適配器轉換成目標介面子類,才能被客戶使用。

五、應用實例

  下麵用鳥叫和鳥飛的例子解析適配器模式,鸚鵡會叫也會飛,但鵝就只會叫不會飛,而且鵝也不是鳥類,我們要創建一個適配器,把鵝轉換成鳥。

  第一步、創建鳥介面,對應角色目標介面

package adapter.pattern;

//鳥介面
public interface Bird {
	//鳥叫
	public void chirp();
	//飛
	public void fly();
}

  第二步、創建鸚鵡類

package adapter.pattern;

//鸚鵡類實現鳥介面
public class Parrot implements Bird{

	public void chirp() {
		System.out.println("嗚嗚嗚");		
	}

	public void fly() {
		System.out.println("我能飛很遠很遠");		
	}

}

  第三步、創建鵝類,對應角色被適配者

package adapter.pattern;

//鵝類,不是鳥
public class Goose {
	//鵝會叫但不會飛,沒有飛的方法
	public void chirp(){
		System.out.println("嘎嘎嘎");
	}
}

  第四步、創建適配器

package adapter.pattern;

//適配器,把鵝類適配為鳥
public class GooseAdapter implements Bird{
	//組合鵝類
	Goose goose;
	public GooseAdapter(Goose goose){
		this.goose = goose;
	}
	
	public void chirp() {
		if(goose != null){
			//調用鳥叫的時候委托鵝叫
			goose.chirp();
		}
	}

	public void fly() {
		//不支持該操作,可以拋出該異常,客戶可以知道詳情
		throw new UnsupportedOperationException();
	}

}

  第五步、測試適配器

package adapter.pattern;

public class AdapterTest {
	public static void main(String[] args){
		System.out.println("-----鸚鵡會叫也會飛-----");
		Bird parrot = new Parrot();
		parrot.chirp();
		parrot.fly();
		
		System.out.println("-----鵝會叫但不會飛-----");
		Goose goose = new Goose();
		Bird gooseAdapter = new GooseAdapter(goose);
		gooseAdapter.chirp();
		gooseAdapter.fly();
		
		
	}
}

  運行結果:

  適配器在java中的例子,我們知道ArrayList類實現了迭代器(Iterator),但不支持枚舉(Enumeration),下麵我們就來實現ArrayList的枚舉操作。

package adapter.pattern;

import java.util.ArrayList;
import java.util.Enumeration;

public class ItertorEnumeration implements Enumeration{
	//組合被適配者
	private ArrayList<String> list;
	//集合的計數器,判斷指針指向集合的位置
	private int index = 0;
	public ItertorEnumeration(ArrayList<String> list){
		this.list = list;
	}
	public boolean hasMoreElements() {
		if(list != null && list.size() > index){
			return true;
		}
		return false;
	}

	public Object nextElement() {
		String content = list.get(index);
		index++;
		return content;
	}
}

  

六、優點和缺點

  1、優點

  (1)、轉換介面,適配器讓不相容的介面變成相容。

  (2)、讓客戶和實現的介面解耦。有了適配器,客戶端每次調用不相容的介面時,不用修改自己的代碼,只要調用適合的適配器就可以了。

  (3)、使用了對象組合設計原則。以組合的方式包裝被適配者,被適配者的任何子類都可以搭配著同一個適配器使用。

  (4)、體現了“開閉”原則。適配器模式把客戶和介面綁定起來,而不是和具體實現綁定,我們可以使用多個配適器來轉換多個後臺類,也可以很容易地增加新的適配器。

  2、缺點

  (1)、每個被適配者都需要一個適配器,當適配器過多時會增加系統複雜度,降低運行時的性能。

  (2)、實現一個適配器可能需要下一番功夫,增加開發的難度。

七、使用場景

  1、當要使用的兩個類所做的事情相同或者相似,但是具有不同的介面時考慮使用配適器模式。

  2、當需要統一客戶端調用介面的代碼,而所調用的介面具有不相容問題時使用適配器模式。這樣客戶端只有調用一個介面就行了,這樣可以更簡單、更直接、更緊湊。

八、總結

  1、適配器有對象適配器和類適配器,類適配器需要用到多重繼承。

  2、適配器就是轉換介面達到我們的需要。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 學習Hibernate ,我們首先要知道為什麼要學習它?它有什麼好處?也就是我們為什麼要學習框架技術? 還要知道 什麼是Hibernate? 為什麼要使用Hibernate? Hibernate的配置文件的作用是什麼? Hibernate映射文件的作用是什麼? Hibernate持久化對象的狀態有哪 ...
  • nodejs windows下的調用方法: C:\Users\owen>node helloworld.jsHello WorldHello: 25 C:\Users\owen>node getmodule.jsHello BYVoid C:\Users\owen>node app.jsHTTP S ...
  • 在Eclipse 創建動態WEB 工程,在src 下 創建 config.xml: 提示Error: Content is not allowed in prolog 查看為DOM 解析xml error, 查看網上加入 dom4j.jar,refrensh並無效果; // 解決辦法: 用記事本創建 ...
  • 實例運行結果如下 實例運行結果如下 ...
  • 今天寫了個java類連接oracle,拋出了這個問題 java.sql.SQLException: No suitable driver found for jdbc:oracle:thin:@127.0.0.1:1521:orcl; 很顯然是URL錯誤,以前碰到過類似的問題,故一起總結一下。 以前 ...
  • 前言:關於EL表示式開發用的非常多,現在我們回顧一下關於如果去操作EL表達式 1:EL表達式語法 所有EL表達式都是由{開始}結束,表達式中用.和[]操作符來訪問數據比喻${user.userName}、${user["userName"]}是等效的。 2:幾個重要的操作符 算術,邏輯,關係操作符和 ...
  • 學習設計模式的過程中,發現相關的作者們都會用UML類圖來表示一個模式的整體脈絡,這種方式確實直觀明瞭,既能體現巨集觀思路、又能兼顧實現細節。真的是很妙的工具。在開始正式學習設計模式之前,有必要對UML有個大概的掌握。然後,日後有望解鎖更多關於UML方面的技能,比如說:建模。哈哈,有點小興奮呢。 UML ...
  • 一、概述 外觀模式提供了一個統一的介面,用來訪問子系統中的一群介面。外觀定義了一個高層介面,讓子系統更容易使用。 二、解決問題 在上一講中,我們學習了適配器模式,它是用來轉換一個介面的,而外觀模式可以理解為轉換一群介面,客戶只要調用一個介面,而不用調用多個介面就可以達到目的。想想現實生活中例子,我們 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...