團隊中對面向對象的理論研究已經做了很長時間,大家對接口,封裝,繼承,多态以及設計模式什麼的似乎都能說出點東西來,但當看代碼時發現大家其實并不十厘清楚具體怎麼做,是以我就想了個題目讓大家來做,然後進行了一次頭腦風暴,過程記錄如下:
題目内容:
需要處理三種産品圖書,數位,消費,需要計算産品的稅率,圖書的稅率為價格的0.1,數位和消費類産品為價格的0.11,需要獲得三種産品的資訊,圖書和消費類産品的資訊為:"名字:" + Name;,數位産品的資訊為:"數位類名字:" + Name;
要求:符合ocp原則(不懂ocp原則的到網上去查,變化點在計稅的方式可能改變,資訊列印方式可能改變)
這裡我給大家一個面向過程的版本,友善大家了解需求
代碼
測試代碼
這個過程化的版本的問題如下:
1、當更改稅率或獲得資訊時需要修改product類,這不符合ocp原則
2、product類的職責也太多了
當然如果就隻是這麼簡單的需求的話,這個過程化的版本也不錯,至少簡單。
第一個方案:
Product類
Tax類
<a></a>
class Tax
{
public double ComputeTax(double price, double taxRate)
{
return price * taxRate;
}
}
ProductInfo
這個方案其實完全沒有解決問題,而且還比原來的方案更複雜了。新的稅率仍然要改代碼,新的資訊仍然要改代碼。
第二個方案:
Product
CreateProduct
interface ITax
double CoumputeTax(double price);
Main
這個方案似乎是解決了問題,新的稅率變化添加一個新類繼承ITax接口,在用戶端用即可。但這種方案顯然屬于知識學太多了,混用了委托與接口,無端的增加的複雜度,CreateProduct完全沒有存在的必要。
第三種方案:
這是使用委托來實作的方案,我覺得這個方案符合了需求,也符合了ocp原則,但和接口方案還是有差別的,我們先看看接口組合方案:
第四種方案:
我覺得對于這個需求來說方案三和方案四都應該算是符合要求的比較好的解決方案,這兩種方案各有優缺點。
方案三(委托方案)的優點:
1、足夠靈活
2、代碼簡單,類少
缺點:
1、缺乏限制,隻要符合計稅委托簽名的方法就可以計算稅率,往往會造成已實作的業務代碼職責不夠清晰。
方案四(接口方案)的優點:
1、職責明确
2、也足夠靈活
1、使用的類往往過多
接口和委托的差別:
接口(interface)用來定義一種程式的協定。實作接口的類或者結構要與接口的定義嚴格一緻。接口(interface)是向客戶承諾類或結構體的行為方式的一種合同,當實作某個接口時,相當于告訴可能的客戶:“我保證支援這個接口的方法,屬性等”,接口不能執行個體化,接口隻包含成員定義,不包含成員的實作,成員的實作需要在繼承的類或者結構中實作。
C#中的委托是一種引用方法的類型,一旦為委托配置設定了方法,委托将與該方法具有完全相同的行為,委托方法的使用可以像其他任何方法一樣具有參數和傳回值。委托對象能被傳遞給調用該方法引用的代碼而無須知道哪個方法将在編譯時被調用。
從定義上來看似乎委托和接口沒什麼相似之處,但從隔離變化這個角度來看他們倒是有些相似之處,是以這裡我們把他們放到一起來比較一番。
委托和接口都允許類設計器分離類型聲明和實作。給定的接口可由任何類或結構繼承和實作;可以為任何類中的方法建立委托,前提是該方法符合委托的方法簽名。接口引用或委托可由不了解實作該接口或委托方法的類的對象使用。既然存在這些相似性,那麼類設計器何時應使用委托,何時又該使用接口呢?
在以下情況中使用委托:
當使用事件設計模式時。委托是事件的基礎,當需要某個事件觸發外界響應時,使用委托事件比較合适。
當調用方不需要通路實作該方法的對象中的其他屬性、方法或接口時。
需要友善的組合,使用委托可以利用+=,-=友善的組合方法。
當類可能需要該方法的多個實作時,使用多點傳播委托。
在以下情況中使用接口:
當存在一組可能被調用的相關方法時。
當類隻需要方法的單個實作時。
當使用接口的類想要将該接口強制轉換為其他接口或類類型時。
當正在實作的方法連結到類的類型或辨別時:例如比較方法。
使用單一方法接口而不使用委托的一個很好的示例是 IComparable 或 IComparable。IComparable 聲明 CompareTo 方法,該方法傳回一個整數,以指定相同類型的兩個對象之間的小于、等于或大于關系。IComparable 可用作排序算法的基礎,雖然将委托比較方法用作排序算法的基礎是有效的,但是并不理想。因為進行比較的能力屬于類,而比較算法不會在運作時改變,是以單一方法接口是理想的。
本文轉自 你聽海是不是在笑 部落格園部落格,原文連結:http://www.cnblogs.com/nuaalfm/archive/2010/04/09/1708543.html ,如需轉載請自行聯系原作者
<a href="http://blog.csdn.net/nuaalfm/archive/2007/08/12/1739746.aspx" target="_blank"></a>