C#學習筆記-適配器模式

来源:http://www.cnblogs.com/Aries-rong/archive/2017/11/15/7837972.html
-Advertisement-
Play Games

什麼是適配器模式? 適配器模式(Adapter):將一個類的介面轉換成客戶希望的另外一個介面。 Adapter模式使得原本由於介面不相容而不能一起工作的那些類可以一起工作。 什麼時候運用適配器模式? 在想使用一個已經存在的類時,如果它的介面,也就是它的方法與我們當前的要求不相同時,就需要考慮用到適配 ...


什麼是適配器模式?

   適配器模式(Adapter):將一個類的介面轉換成客戶希望的另外一個介面。

   Adapter模式使得原本由於介面不相容而不能一起工作的那些類可以一起工作。

什麼時候運用適配器模式?

   在想使用一個已經存在的類時,如果它的介面,也就是它的方法與我們當前的要求不相同時,就需要考慮用到適配器模式了。

   一般而言,使用適配器模式是出於無奈之舉,一般存在於軟體開發後期或者維護期,在軟體設計階段,我們還是儘量避免該模式的使用。

適配器模式的組成

    Target:目標介面,也就是客戶所期待的介面。目標可以是具體的或者抽象的類,也可以是介面。

  Adpatee:需要適配的類。也就是我們需要與目標介面對接成功的類。

  Adapter:中間起到鏈接作用的類。通過在內部包裝一個Adptee對象,將源介面轉換成目標介面。

適配器模式具體實現

適配器模式的結構

   

適配器模式的實現

Target類:也就是目標類

1 class Target
2 {
3     public virtual void Request()
4     {
5          Console.WriteLine("普通請求");
6      }
7 }

Adaptee類:需要適配的類

1 class Adaptee
2 {
3      public void SpecificRequest()
4      {
5          Console.WriteLine("特殊請求");
6      }
7 }

Adapter類:

 1 class Aapter : Target
 2 { 
 3      private Adaptee adaptee = new Adaptee();
 4      /// <summary>
 5      /// 這樣就可以把錶面調用Request()方法變成實際調用SpecificRequest()
 6      /// </summary>
 7      public override void Request()
 8      {
 9           adaptee.SpecificRequest();
10       }
11 }

主函數調用:

1 static void Main(string[] args)
2 {
3        //對客戶端來說,調用的是Target的Request()
4        Target target = new Aapter();
5        target.Request();
6 
7         Console.Read();
8 }

實例解析

   為了深化理解,我們準備一個具體的實例來分析。

   姚明作為一個外籍的球員在進入NBA初期,由於英文水平一般,常常聽不懂教練的指揮與安排,需要翻譯來全程跟隨以實現溝通。請就此來寫出具體的情況。

 分析:

   在這裡,我們不難發現教練的指揮與安排就是Target,姚明就是Adaptee,而翻譯就理所當然成了Adapter,那麼我們就能分析出彼此的關係了。

  

具體實現:

  1     class Program
  2     {
  3         static void Main(string[] args)
  4         {
  5             Player b = new Forwards("A");
  6             b.Attack();
  7 
  8             Player m = new Guards("B");
  9             m.Attack();
 10             
 11             //通過翻譯,姚明知道了需要做的事情
 12             Player ym = new Translator("姚明");
 13             ym.Attack();
 14             ym.Defense();
 15 
 16             Console.Read();
 17         }
 18 
 19         abstract class Player
 20         {
 21             protected string name;
 22             public Player(string name)
 23             {
 24                 this.name = name;
 25             }
 26             public abstract void Attack();
 27             public abstract void Defense();
 28         }
 29         /// <summary>
 30         /// 前鋒
 31         /// </summary>
 32         class Forwards : Player
 33         {
 34             public Forwards(string name) : base(name)
 35             {
 36             }
 37             public override void Attack()
 38             {
 39                 Console.WriteLine("前鋒{0} 進攻", name);
 40             }
 41             public override void Defense()
 42             {
 43                 Console.WriteLine("前鋒{0} 防守", name);
 44             }
 45         }
 46         /// <summary>
 47         /// 中鋒
 48         /// </summary>
 49         class Center : Player
 50         {
 51             public Center(string name) : base(name)
 52             {
 53             }
 54             public override void Attack()
 55             {
 56                 Console.WriteLine("中鋒{0} 進攻", name);
 57             }
 58             public override void Defense()
 59             {
 60                 Console.WriteLine("中鋒{0} 防守", name);
 61             }
 62         }
 63         /// <summary>
 64         /// 後衛
 65         /// </summary>
 66         class Guards : Player
 67         {
 68             public Guards(string name) : base(name)
 69             {
 70             }
 71             public override void Attack()
 72             {
 73                 Console.WriteLine("後衛{0} 進攻", name);
 74             }
 75             public override void Defense()
 76             {
 77                 Console.WriteLine("後衛{0} 防守", name);
 78             }
 79         }
 80         /// <summary>
 81         /// 翻譯是繼承於運動員的,因為他需要直接理解教練的意思
 82         /// 但是他實際需要傳達的是外籍球員,所以他調用的是外籍球員所理解的方法=>也就是翻譯的作用
 83         /// </summary>
 84         class Translator : Player
 85         {
 86             private ForeignCenter fc = new ForeignCenter();
 87             public Translator(string name) : base(name)
 88             {
 89                 fc.Name = name;
 90             }
 91             public override void Attack()
 92             {
 93                 fc.進攻();
 94             }
 95             public override void Defense()
 96             {
 97                 fc.防守();
 98             }
 99         }
100         /// <summary>
101         /// 作為外籍球員,他有自己的姓名和進攻防守方式等
102         /// 其他的事情交給翻譯就好了
103         /// </summary>
104         class ForeignCenter
105         {
106             private string name;
107             public string Name
108             {
109                 get { return name; }
110                 set { name = value; }
111             }
112             public void 進攻()
113             {
114                 Console.WriteLine("外籍中鋒{0} 進攻", name);
115             }
116             public void 防守()
117             {
118                 Console.WriteLine("外籍中鋒{0} 防守", name);
119             }
120         }
121     }

適配器模式的優缺點

   像之前提到的適配器能在後期維護的時候起到很大的作用,能在開發新的功能的時候保護原來軟體的穩定性,但是初期的時候還是能避免就儘量避免吧!

 

 

備註:文中所有代碼及知識點均來自於《大話設計模式》,本人屬於邊學邊看邊敲代碼邊總結的階段。


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

-Advertisement-
Play Games
更多相關文章
  • 要生成對象並通過名稱空間註入屬性的類 代碼如下: XML配置文件寫法如下: 生成對象及屬性值調用方法,代碼如下: ...
  • 作者:NiceCui 本文謝絕轉載,如需轉載需徵得作者本人同意,謝謝。 本文鏈接:http://www.cnblogs.com/NiceCui/p/7835122.html 郵箱:[email protected] 日期:2017-11-14 22:26 將枚舉作為參數傳遞在複雜的服務調用中也是很常 ...
  • 鍵盤操作 功能 Alt + / 語句或變數名自動補全 Ctrl + Shift + F 語句格式化 Ctrl + / 單行註釋(或取消單行註釋) Ctrl + Shift + / 多行註釋 Ctrl + Shift + \ 取消多行註釋 Ctrl + Shift + o 快捷導包 Alt + 上下箭 ...
  • Given a positive integer N, your task is to calculate the sum of the positive integers less than N which are not coprime to N. A is said to be coprime ...
  • 記錄下麵試裡面遇到的一些java盲區,一方面掃描自己的知識盲區,一方面也可以給後面面試的朋友一些警示,以免面試的時候出現不知道的尷尬情況。 提出問題:父類靜態屬性,父類屬性,父類構造方法,子類靜態屬性, 子類屬性,子類構造方法的初始化順序? 提出猜想:父類靜態屬性=> 父類屬性=> 父類構造方法= ...
  • 靜態方法和實例方法的區別主要體現在兩個方面: 在外部調用靜態方法時,可以使用"類名.方法名"的方式,也可以使用"對象名.方法名"的方式。而實例方法只有後面這種方式。也就是說,調用靜態方法可以無需創建對象。 靜態方法在訪問本類的成員時,只允許訪問靜態成員(即靜態成員變數和靜態方法),而不允許訪問實例成 ...
  • 有一個模式可以幫助你的對象知悉現況,不會錯過該對象感興趣的事,對象甚至在運行時可以決定是否要繼續被通知,如果一個對象狀態的改變需要通知很多對這個對象關註的一系列對象,就可以使用觀察者模式 。觀察者模式也是JDK中使用最多的一個設計模式,而我們本章討論的就是它。 那麼首先,我們先來看一看此模式的定義: ...
  • 首次接觸倉儲的概念來自Eric Evans 的經典著作《領域驅動設計-軟體核心複雜性應對之道》,但書中沒有具體實現。如何實現倉儲模式,在我這幾年的使用過程中也積累了一些具體的實施經驗。根據項目的大小、可維護性、可擴展性,以及併發我們可以做以下幾種設計; 1、項目小,擴展性差 public inter... ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...