DotNet中設計的類或者架構大部分都可以跟某個設計模式對應的上,因此理解一些設計模式的內容有助於提高對dotnet的認識,可以更深刻的認識這些類的使用。顯然dotnet中的類的設計絕對稱得上是專業的,我們在設計自己的類時可以作為參考,提高設計的品質。
最近在HeadFirst DesignPattern一書中看到Iterator和Composite模式的介紹,書中講的內容是以java為例子,講述了如何使用Iterator介面去實現對集合的迭代,應用Iterator模式。之後介紹了使用統一基類的方法去管理子節點和父節點,從而實現Compostie模式的應用。看完之後,我覺得這些應用同樣在dotnet中也是隨處可見的,只不過類的名稱有些不同,而且在dotnet方面用起來還更加的方便。接下來看看dotnet中分別使用了這兩種設計模式的執行個體。
對於迭代模式,在java5之前只能通過Enumeration類來實現迭代,具體方式是在每個類中添加一個返回Enumeration對象的;之後就出現了更加進階的Iterator類,具體用法都差不多,但是有了類似於dotnet的foreach的迭代方式,但是仍可以通過方法返回一個迭代器。而dotnet中的實現方式也基本類似,dotnet中利用IEnumerator介面實現Iterator的功能,但是dotnet要求集合類實現IEnumerable介面才可以用foreach方式迭代,然後每個對象返回各自的IEnumerato。當然原始的方法也是支援的,也就是手動的返回一個IEnumerator,然後迴圈的調用next方法。另外dotnet中返回IEnumerator的方式還有更簡便的方法,可利用yield關鍵字實現,具體可查看msdn。兩種語言的最終顯示目的都是相同的,那就是通過一個統一的基類或介面實現對不同集合的迭代,實現抽象與具體實現的分離。
接下來是組合模式,這種模式的對於實現層級關係的處理有很靈活的擴充性,同樣也是利用了基類或統一介面的方式(似乎設計模式都離不開基類或介面)。這種模式的具體做法是用一個相同的基類去對待子節點和父節點,這樣在client調用時就不需要去考慮到底是什麼節點,只知道它是一個節點。這種層級關係的例子很容易讓人想到xml。dotnet中通過XmlNode去統一管理所有的Xml節點,然後提供HasChildNode的方法判斷是否有子節點,這個方法通常用於遞迴的迭代所有的子節點;在IO方面,dotnet提供了FileSystemInfo基類去統一管理檔案和檔案夾,這也是種典型的層級關係。不過在IO中,檔案和檔案夾具有自己各自不同名稱的類,FileInfo和DirecotryInfo。java也有類似的方式,不過在java中基類統一了大部分的方法,比如某些子節點調用會出問題的方法都放在基類中。dotnet則比較安全,但是要調用具體各自的方法時就有點點麻煩;gui方面的也有體現,比如典型的Menu和MenuItem,這種實現方式有一點點差別,那就是MenuItem繼承了Menu,更明顯的體現出父子關係,同樣也達到了統一介面的目的,使用的時候通過IsParent判斷是否為父節點。
組合模式帶來的方便更多體現在遞迴迭代,進一步跟迭代器結合起來將會帶來極高的靈活性。