一個插排引發的設計思想 (三) 委托與事件

来源:https://www.cnblogs.com/FlyLolo/archive/2018/02/01/8392848.html
-Advertisement-
Play Games

一個插排引發的設計思想 (一) 觀察者模式 一個插排引發的設計思想 (二) 抽象類與介面 一個插排引發的設計思想 (三) 委托與事件 ...待續.... 前兩篇文章循序漸進的介紹了觀察者模式、抽象類和介面, 並分析了抽象類和介面的不同. 結尾處有這樣的問題: 無論是抽象類還是介面, 都是將設備本身放 ...


一個插排引發的設計思想 (一) 觀察者模式

一個插排引發的設計思想 (二) 抽象類與介面

一個插排引發的設計思想 (三) 委托與事件

...待續....

 

前兩篇文章循序漸進的介紹了觀察者模式、抽象類和介面, 並分析了抽象類和介面的不同.

結尾處有這樣的問題:

無論是抽象類還是介面, 都是將設備本身放入了插排的集合中, 那麼我們是否可以將此處的參數改為設備的Input方法呢?

那麼我們就用到了委托Delegate.

1    public delegate void InputDelegate(int left, int right);

看到接下來的代碼, 老鳥別笑, 請允許我"循序漸進"的引導著思路重構.

我們用委托InputDelegate定義了插頭的標準. 那麼原來的代碼改變一下

一. 用方法作為參數傳遞, 代替原來的整個設備

 1     public delegate void InputDelegate(int left, int right);
 2     public class OutPut
 3     {
 4         public OutPut()
 5         {
 6             this.EACollection = new List<InputDelegate>();
 7         }
 8         private List<InputDelegate> EACollection;
 9         public void powered(int left, int right)
10         {
11             foreach (var item in EACollection)
12             {
13                 item(left, right);
14             }
15         }
16         public void AddInput(InputDelegate item)
17         {
18             EACollection.Add(item);
19         }
20 
21         public void RemoveInput(InputDelegate item)
22         {
23             EACollection.Remove(item);
24         }
25     }
26 
27     class Program
28     {
29         static void Main(string[] args)
30         {
31             OutPut op = new OutPut();
32             op.AddInput(new TV().Input);
33             op.AddInput(new ElectricKettle().InputAAAA);
34 
35             op.powered(220, 0);
36 
37             Console.ReadKey();
38         }
39     }

原來的TV和ElectricKettle無需任何繼承任何抽象類和介面, 只要有和定義的Delegate一樣的方法簽名的方法即可.

甚至名字都可以不一樣, 例如ElectricKettle的input方法我隨便改了一下改成了InputAAAA依然沒問題.

 1     public class ElectricKettle
 2     {
 3         public void InputAAAA(int left, int right)
 4         {
 5             Heat();
 6         }
 7 
 8         private void Heat()
 9         {
10             Console.WriteLine("I am heating");
11         }
12     }

通過上面的方法, 我們把插入插排的參數由整個設備改成了設備的插頭. 

功能是實現了, 但Delegate用起來沒必要那麼麻煩, 我們繼續改

二. 用+=和-=來操作

我們改造一下Output類

 1     public delegate void InputDelegate(int left, int right);
 2     public class OutPut
 3     {
 4         public InputDelegate inputDelegate;
 5         public void powered(int left, int right)
 6         {
 7             inputDelegate(left, right);
 8         }
 9     }
10 
11     class Program
12     {
13         static void Main(string[] args)
14         {
15             OutPut op = new OutPut();
16             op.inputDelegate += new TV().Input;
17             op.inputDelegate += new ElectricKettle().InputAAAA;
18 
19             op.powered(220, 0);
20 
21             Console.ReadKey();
22         }
23     }

簡潔多了, 根據Delegate的特性, 插排集本身也被inputDelegate代替了.

在調用的時候, 我們只需將input方法 +=到該inputDelegate即可.

三. 委托和事件

上面的例子貌似已經很好了, 但既然是插排, 也就是可能會有好多插頭來插拔, 而插頭之間互不幹涉, 調用的位置可能存在於系統的任何位置 .

但上面的代碼讓我們想到一個問題,

我們把"集和"暴露出來了, 之前的 private List<IGBElectricalable> EACollection是私有的, 只可以通過add和 remove兩個方法操作.

現在我們把它public了,  哪個搗蛋的寫了一句op.inputDelegate = null,  把插排都弄沒了, 讓別的插頭怎麼辦.

所以我們還希望像原來那樣只提供增減的方法, 不允許賦值, 這裡我們就用到了事件.

 1     public delegate void InputDelegate(int left, int right);
 2     
 3     public class OutPut
 4     {
 5         public event InputDelegate inputEvent;
 6         public void powered(int left, int right)
 7         {
 8             inputEvent(left, right);
 9         }
10     }
11 
12     class Program
13     {
14         static void Main(string[] args)
15         {
16             OutPut op = new OutPut();
17             
18             op.inputEvent += new TV().Input;
19             op.inputEvent += new ElectricKettle().InputAAAA;
20             //op.inputEvent = null;
21             op.powered(220, 0);
22 
23             Console.ReadKey();
24         }
25     }

Output中的 inputDelegate 改為了 inputEvent, inputEvent不再允許通過=來賦值了.

main方法中註釋的一行 //op.inputEvent = null; 測試了一下 , 已經編譯不通過了.

四. 小結

本文通過委托, 將方法作為參數註冊到了插排中.  因為安全問題, 又將委托改為了事件.

 


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

-Advertisement-
Play Games
更多相關文章
  • 各種類型的線條 世界那麼大 ————————— 世界那麼大 ————————— ...
  • 簡介:模態框(Modal)是覆蓋在父窗體上的子窗體。通常,目的是顯示來自一個單獨的源的內容,可以在不離開父窗體的情況下有一些互動。子窗體可提供信息、交互等。 Modal簡介 Modal實現彈出表單 Modal實現刪除提示框 其他用法 Bootstrap 模態框(Modal)插件 模態框(Modal) ...
  • 申請百度統計後,會得到一段JS代碼,需要插入到每個網頁中去,在Vue.js項目首先想到的可能就是,把統計代碼插入到index.html入口文件中,這樣就全局插入,每個頁面就都有了;這樣做就涉及到一個問題,Vue.js項目是單頁應用,每次用戶瀏覽網站時,訪問內頁時頁面是不會刷新的,也就意味著不會觸發百 ...
  • border屬性 border-width border-style border-color inherit border-style的值:none dotted(點線) dashed(虛線) solid(實線) double(雙線) groove(凹槽) ridge(凸起) inset outs ...
  • 強制類型轉換 將值從一種類型轉換為另一種類型通常稱為類型轉換,這是顯式的情況。隱式的情況被稱為強制類型轉換 在書中,作者還提出一種區分方式: 類型轉換髮生在靜態類型語言的編譯階段,強制類型轉換髮生在動態類型語言的運行時。 JS天生的動態類型語言,所以JS中統一講強制類型轉換。 一、JS中的強制類型轉 ...
  • font連寫屬性 font-style font-variant font-weight font-size/line-height font-family font-size與font-family為必填 font-style 可指定的值為: normal(正常) italic(斜體) obliq ...
  • .toggle-cart-enter-active, .toggle-cart-leave-active { transition: all .3s ease-out; } .toggle-cart-enter, .toggle-cart-leave-active { transform: tran ...
  • wx-jq (一套完全原創的微信小程式插件集合庫) 微信小程式插件,微信小程式組件,微信小程式插件集合,微信小程式組件集合,微信小程式插件學習,微信小程式插件開發, 線上演示: 下載地址: https://gitee.com/dgx/wx-jq 效果展示(截圖大部分來自真機蘋果5s,少量來自模擬器) ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...