日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

有效事件: 可取代数十种设计模式

發布時間:2023/12/4 asp.net 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 有效事件: 可取代数十种设计模式 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

編輯寄語

當我讓?MSDN 雜志高級特約編輯 James McCaffrey 審閱本文的初稿時,他為本文作者提出的一些觀點和想法所震怒,憤憤然地離開了。大多數時候,這預示著文稿不通過。但 McCaffrey 指出,軟件工程中的新概念遭到摒棄再常見不過,這完全是因為之前從未有人提出過。雖然 McCaffrey 聲稱自己仍為本文中的諸多觀點而震怒,但我們都認為這篇文章可能會引發很多有關軟件設計和方法范例的思考。- Michael Desmond


只要有軟件,就會有失敗的軟件。研究顯示,所有項目中有 25% 完全失敗,有 50% 可以說是“有缺陷”。 試想想,如果汽車制造商也有相同的統計數據,那就是有 25% 的汽車無法啟動或在開燈時爆炸,有 50% 的汽車僅能達到 25 英里每小時或每英里使用 15 加侖的汽油。更重要的是,如果客戶在付款前并不知道哪款汽車適合自己,情況又如何?這與當前的軟件開發現狀頗為相似。


已提出各種解決方案來改善這種狀況,但均未涉及代碼這一根本原因! 我認為,軟件項目失敗通常可以歸因為同一問題:混亂不堪的代碼。代碼之所以如此糟糕是因為確實沒有辦法適應變更。正因為此,我們建議采用極限編程和敏捷軟件開發等方法。不過,這些方法其實都無法幫助創建更好的代碼。敏捷軟件開發并不能神奇地幫助避免混亂不堪的代碼。必須能夠通過原子構建基塊單獨處理問題,才能變得敏捷。


本文介紹的設計模式并不能替代敏捷軟件開發或其他類似方法。畢竟敏捷軟件開發是一種管理框架,而不是體系結構設計模式。相反,我提出的設計方法可以讓你更輕松地變得敏捷,因為你可以適應變更。在過去幾年里,我開發出了一種設計模式,我將其稱為“有效事件”。 借助這種設計模式,可以創建可重用的小型組件,從而能夠輕松擴展、修改、重用這些組件,并將其與其他部件進行交換。這種設計模式帶來了不同的軟件視角,讓你可以“安排”代碼(幾乎就像是各塊樂高積木)。你可能會認為,這與使用面向對象的編程 (OOP) 范例編寫代碼頗為相似。然而,有效事件與傳統 OOP 有很大區別。



檢查你自己的代碼

幫個忙唄: 打開你在 Visual Studio 中生成的最后一個解決方案,然后檢查依賴項關系圖。可以從你的解決方案中提取多少項目和類? 可以在未來項目中重用多少類? 在不破壞軟件的前提下,可以將多少類替換成其他類?


我猜你的項目和類依賴項與其他大多數項目一樣。你項目的依賴項關系圖很有可能混亂不堪。非常抱歉,我可能太過坦誠,而忽略大家的感受,但這確是我的經驗之談。但請放心,不只你一個人遇到這種問題。雖然沒有確鑿的數據,但我可以說世界上 98% 的代碼都存在同樣的問題。此外,我不會強迫大家去面對這個問題,除非我有解決方案。


如果可以理清這些依賴項并創建可重用的組件,這樣代碼的各個部分就都不會引用其他任何部分,那么你的編程質量將會大大提高。如果你的項目和類不像現在這樣混亂,就可以更容易地交換各個部分了。如果理清了你的類,便可以在未來項目中重用它們。如果你的項目最大限度地減少了依賴項,那么你將擁有一組更有可能重用的組件,而不是一個龐然大物。有效事件可推進跨類和項目不使用依賴項。若要解決軟件混亂不堪的問題,零依賴項是唯一可接受的數字!


有效事件的工作原理是什么?

有效事件設計模式實際上極其易于理解。與其創建接口來分隔邏輯塊的實現和使用者,不如直接使用屬性來標記方法。例如:


[ActiveEvent (Name = “foo.bar”)]protected static void foo_bar(ApplicationContext context, ActiveEventArgs e) {var input = e.Args[“input”].Value as string;e.Args.Add(“output”, “Hello there ” + var); }


此語法取自 Phosphorus Five,這是我創建的一個開放源代碼有效事件實現。有關詳細信息,請參閱“幾乎不存在的軟件”。


若要調用已定義的方法,使用有效事件范例同樣十分簡單。通過有效事件名稱間接調用方法,而不是直接調用:


/* ... some method in another assembly ... */var args = new Node (); args.Add ("input", "John Doe");/* context is your ApplicationContext instance, which keeps ?? track of your Active Events */var result = context.Raise ("foo.bar", args)["output"].Value as string;


引發調用調用的是 foo.bar 有效事件。請注意,在有效事件調用及其實現之間沒有依賴項。此外,它們之間沒有共用的公共類。只有數據在事件中傳入和傳出。此外,還請注意,所有有效事件的簽名都完全相同。因此,類、接口和方法略微轉向幕后,并且在源代碼中的受重視程度降低。


有效事件組件的加載完全是一個動態過程,可以通過應用程序配置文件中引用的程序集列表完成,也可以通過從文件夾自動加載所有 DLL,然后將其注冊為有效事件處理程序來完成。在內部,有效事件“內核”會在加載期間遍歷 DLL 中的所有類型,并對有效事件方法的 MethodInfo 引用存儲到字符串/MethodInfo 字典中。稍后會在調用事件時使用此字典。若要限定有效事件的范圍或將其與狀態相關聯,可以動態添加類實例作為有效事件偵聽器,并使用實例方法(而不是靜態方法)作為有效事件接收器,這便是(舉例來說)Phosphorus Five 中的 plugins/p5.web 項目完成的工作。


這會創建一個環境,其中不同的代碼部分都是簡單的構建基塊,彼此間接調用,以便你可以輕松地將任意一個有效事件程序集與另一個實現進行交換。徹底更改生成的應用程序就像更改配置設置或替換 DLL 一樣簡單。如果愿意,就像將字符串“foo.bar”更改為“foo.bar-2”一樣簡單。 同時,解決方案中的每個程序集仍能調用其他程序集中的方法,而不需要像普通舊數據 (POD) 結構一樣與另一方進行共享。基本上來說,有固定的“另一抽象層”可供任意使用。換言之,組件已原子化。


讓我們將此與需要在傳統 OOP 中執行的操作進行比較。首先,假設使用的是按接口設計方法,且有一個接口和至少一個接口實現。可能需要使用抽象工廠方案來創建對象,具體視應用場景而定。因此,需要創建兩個類和一個接口,很容易就總共有 30 行以上代碼。此外,若要根據實現創建真正的插件,最終會為使用者部分生成一個項目(使用插件),并為實現部分生成一個項目(實現接口的含類項目)。若要采用完全模塊化的方法,可以使用第三個項目來包含接口和可能的抽象工廠。然后,查看結果時,你會發現最終在三個項目中生成了至少三個交叉組件引用。此外,只有修改所有三個項目,才能添加或更改接口的輸入或輸出部件。將這與有效事件示例生成的單行解決方案相比,后者根本就沒有引用,向它提供任何輸入或輸出自變量,都不要緊。傳統方法的代碼行可能有兩倍之多或更多,根據我的經驗,會生成更復雜的依賴項關系圖、更嚴格的結果和更復雜的代碼。


OOP 不是 OO

我喜歡 OOP。那是一個極好的范例,可方便你輕松封裝代碼邏輯、方法和數據。不過,也有人指出,OOP 沒有完全解決所有編碼問題。在某些情況下,使用 OOP 時,必須定義多個類,這些類通常會緊密耦合,并創建依賴項。


在 OOP 中,需要知道方法的簽名,需要擁有對接口的訪問權限,也需要知道如何創建此接口的實例。此外,通常還需要在接口的使用者部分和實現部分之間共享類型。這將在構建基塊中創建依賴項。使用 OOP,僅僅為了創建一個簡單的“Hello World”插件,而需要創建多個類再常見不過。如果更改 OOP 接口,除非你是很認真地設計接口,否則可能需要重新編譯多個程序集。最終可能會有許多抽象接口和樣本代碼,或者不得不接受以下事實:更改接口有可能引起多米諾效應,需要額外更改大量代碼。只要某事物變得過于復雜,或需要完成大量繁瑣重復的工作,你的直覺應該就會認為這是不對的。


問問自己下面這個問題: “如果 OOP 允許創建面向對象的 (OO) 軟件,為什么還很難成功地使用它?” 在我看來,OOP 并不等同于 OO。如果等同,就不需要為了充分利用它而了解這么多的設計模式。


按照目前的做法,我認為 OOP 存在一些根本性的限制,為了充分利用 OOP 而需要了解所有這些設計模式就是體系結構存在以下更為基本的-問題的癥狀:無法交付 OO 軟件。有效事件可以解決這些問題,不是通過實現更好的抽象工廠或新的類構造,而是通過更改方法和函數的調用方式,完全剔除 OOP。若要創建 OO 軟件,需要的不是實例化抽象類和接口的新方法,而是不同的功能調用機制,以及調用的每個接口方法能否共用一個簽名。


幾乎不存在的軟件?

有關展示了有效事件廣泛應用范圍的示例,請查看 Phosphorus Five (github.com/polterguy/phosphorusfive)。Phosphorus Five 是一個大型軟件項目,而有效事件實現僅用了 1.000 行代碼。有關有效事件實現,可以訪問?core/p5.core


在這個項目中,我創造了新的編程語言 Hyperlambda,用于創建有效事件掛鉤。這樣一來,我就可以根據需要更改 for-each 和 while 語句的實現。我還可以將 else 語句擴展為在另一臺服務器上執行。我可以將編程語言輕松擴展為創建我自己的域特定關鍵字,以執行解決任何域問題所需的操作。


我還創造了一種文件格式,用于以一段文字的形式動態聲明節點結構,并將其存儲到我的磁盤或我的數據庫。此外,我還創造了自己的表達式語法,用于引用樹任何部分內的任意節點。這樣就生成了非編程語言(我喜歡這樣稱呼),完全是圖靈完備語言。我的非編程語言既不用動態解釋,也不用靜態編譯;有時只需五行代碼就能完成其他編程語言要用數百行代碼才能完成的操作。


借助有效事件、Hyperlambda 和托管的 AJAX 庫(僅包含一個 AJAX 小組件),在未引入“Web OS”等名稱的情況下,我成功創造了一些自己不知道如何稱呼的事物。 Phosphorus Five 中大約有 30 個項目,不同的插件中沒有任何引用。所有項目都只引用有效事件實現 p5.core 和表達式引擎 p5.exp。就是這樣。核心文件夾中的主要網站項目 p5.website 只包含一個簡單的容器小組件,幾乎不含邏輯。應用程序啟動期間,所有插件均在我的 Global.asax 中動態加載。盡管如此,所有項目都能動態調用其他項目內的功能。既沒有引用、沒有依賴項,也沒有出現任何問題!


回歸基本

解決方案總是蘊含在問題之中。自相矛盾的是,OOP 旨在解決的一些問題(全局函數和數據)反而成為 OOP 無意間引發的問題的解決方案。如果你看看有效事件這種設計模式,首先會發現的是,在某種程度上,它是回歸基本的,同時使用全局函數取代方法和類。然而,由于無需在有效事件的使用者和實現之間知道并共享簽名或類型,因此與使用 OOP 相比,環境更像是黑盒。這樣一來,可以輕松地進行交換,例如,將 SaveToDatabase 與 InvokeWebService 或 SaveToFile 進行交換。沒有接口、類型、POD 結構和類,只有一個共用簽名。只有優質的普通舊數據。數據只會傳入傳出!


實現多形性和更改字符串一樣簡單。下面的示例展示了如何使用有效事件實現多形性:


string myEvent = "some-active-event";if (usePolymorphism) {myEvent = "some-other-active-event"; } context.Raise (myEvent);


我意識到,經驗豐富的構架師一定會認為這種多形性構造幼稚可笑且簡單粗糙。然而,這種簡單性正是它奏效的原因所在。借助有效事件,可以從數據庫、配置文件或通過用戶在窗體文本框中提供名稱來提取方法或函數的名稱。可以將此看作是不需要顯式類的多形性變體。這是不含類型的多形性。這是在運行時期間動態確定的多形性。通過剔除所有關于多形性的傳統觀念,并重構多形性的實質內容,最終會生成實際有效的多形性(封裝和多形性),而不含類、類型、接口或設計模式。鏈接有效事件就像原子結合成分子一樣簡單。這就是敏捷軟件!


唯一需要的圖類型 Node.cs

使用有效事件,將在有效事件中僅傳入傳出數。這樣一來,可以松散耦合組件。為此,需要使用一個數據類,這也是在使用有效事件范例時唯一需要的一個圖類型。類需要能夠封裝所有可能類中的全部可能字段和屬性。在 Phosphorus Five 中,此類名為 Node.cs,就是包含鍵/值/子設計的圖對象。


成功實現有效事件的關鍵是,節點類是允許有效事件作為輸入接收并作為輸出返回的唯一自變量。事情就是這么湊巧,幾乎所有類都可以有效地縮減成鍵/值/子圖 POD 對象。與有效事件程序集的動態加載相結合,這可以大大減少項目之間的依賴項數。


若要實現 Node.cs,必須能夠保留鍵或名稱、可以是任意對象的值和節點的“子”集合。如果節點類符合這些約束,可以將幾乎所有可能的對象輕松轉換成節點實例。對于熟悉 JSON 或 XML 的人來說,這一點的相似性可能就非常明顯。下面的簡化偽代碼展示了節點類結構:


class Node {public string Name;public object Value;public List<Node> Children; }


在內部,可以在組件內根據需要使用盡可能多的 OOP。然而,當一個組件需要調用另一個組件中的邏輯時,必須以某種方式將所有輸入數據都轉換成節點實例。從有效事件返回信息時,也需要完成同樣的操作。不過,在組件內,可以根據需要使用任意類、接口、抽象工廠、外觀組件、單一實例和設計模式。而外部只有節點,并且有效事件是組件之間的橋梁。將有效事件看作是協議,將節點看作是它的數據,如果這樣有助于你在腦海中勾勒兩者之間的關系的話。


總結

雖然旨在取代當今世界上的其他大多數設計模式,但有效事件并不是靈丹妙藥。除其他事項外,這項技術還會帶來一定開銷。例如,需要進行字典查找,而不是直接調用方法。此外,方法還使用一些反射。這些間接方法調用可能是多個數量級的,相比傳統的虛擬方法調用更加昂貴。此外,只要與其他組件有接口,就需要將對象轉換成節點和數據。


然而,有效事件不應替代你的所有工作。我們的想法是在組件之間提供更好的接口。鑒于此,性能開銷就不是主要問題。如果實際實現需要 5,000,000 個 CPU 周期,那么不論是需要 5 個 CPU 周期,還是需要 500 個 CPU 周期才能調用 SaveToDatabase 方法,都是風馬牛不相及! Donald Knuth 曾經說過,“過早的優化是萬惡之源。”


每當考慮編寫接口時,應該問問自己,改為創建有效事件是否會更好。積累了一些有效事件經驗后,你對這個問題的回答往往是“可能會”。 借助有效事件,大多數時候,接口和抽象類的受重視程度降低。


我知道這聽起來像是荒謬大膽的立場,但看看“幾乎不存在的軟件”中介紹的 Phosphorus Five 項目。 在 Hyperlambda(我為有效事件創造的“語言”)中,對象可以是文件、文件夾、lambda 回叫、圖節點樹的子部分、取自數據庫的一段文字,或通過 HTTP 發送的一段數據。所有對象都可以執行,就像是計算機可理解的執行樹。在 Hyperlambda 中,理論上可以執行數字 42。


我第一次想到有效事件是在七年多前,直覺告訴我有效事件有一種內在的美。問題在于,有效事件挑戰了 60 年來的傳統編程智慧。有效事件甚至成為必須重構最佳做法的促使因素。我花了七年時間才忘掉以前所學,跟著自己的直覺走。有效事件存在的最大問題實際上并不是它的實現,而是在于你的想法。事實上,我完全重構了 Phosphorus Five 五次,這就證明了這一點。


在本文的初稿中,我創造了幾十個類比。通過關聯物理和生物等其他學科的既有知識,我試圖讓大家相信有效事件的優勢。在第二份草稿中,我試圖激怒大家。我的想法是刺激你來證明我是不對的,這樣你就會來找我立場的缺陷,當然你是發現不了任何缺陷的。然而,在我的第三份也是最后一份草稿中,我決定直接介紹有效事件。如果你順著思路走下去,那么有效事件將是成為你唯一需要學習的設計模式。



Thomas Hansen?自 8 歲起便一直在開發軟件,他于 1982 年就開始使用 Oric-1 計算機編寫代碼。編寫的代碼偶爾確實是利大于弊。他對 Web、Ajax、敏捷方法和軟件體系結構充滿熱情。


衷心感謝以下 Microsoft 技術專家對本文的審閱:?James McCaffrey


原文地址:https://msdn.microsoft.com/en-us/magazine/mt795187


.NET社區新聞,深度好文,微信中搜索dotNET跨平臺或掃描二維碼關注

總結

以上是生活随笔為你收集整理的有效事件: 可取代数十种设计模式的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。