面向對象思想(3)

相對於面向對象思想(2),傳統的編程思想解釋。

  • 來自名爲wanghualiang    的評論

很佩服樓主的發散型思維。但是遠遠還沒到顛覆傳統的地步。
這裏談談我的觀點,
面向對象設計時完全從接口來描述對象本身的特性是不是有問題。
從魚是不是可吃應該只能作爲其一個屬性來辨識,
Class Fish
{
public bool IsEatable;
}
當客戶想吃這條魚的時候,IsEatable
=true;如果是河豚的話就是 False了。
當然有許多種不確定的因素,在可吃不可吃之間。那我們應該
[Flags]
Enum Eattype
{

DeliciousEate,
//美味
Distasteful,
Barbed,
..
}

Class Fish
{
public Eattype eattype;

    我想wanghualiang 的評論代表了相當一部分朋友的看法,從傳統的面向對象思想(或者說普遍接受)的觀點來看這樣做是沒有問題的,甚至還被作爲了Demo寫入了很多的面向對象 的教科書。但是實際上這種看法是存在問題的,至少我個人是這麼認爲的,首先我們需要考慮的問題是:魚自己能不能決定自己能不能吃,能不能決定自己好不好 吃?應該是不能吧,決定魚能不能吃,好不好吃的應該是吃魚的對象對吧。也許從普通人的角度來看河豚是不能吃的,但是從高明的大廚或者資深的老饕的角度來看 河豚就是無比的美味了,這也是我在序章的最後專門添加一幅圖片重點解說對象行爲的原因。
    話說回來,既然魚不能決定能不能吃、好不好吃,也就是說明能不能吃的行爲不是有魚能夠決定的,那麼也許有人會問那爲什麼要實現IEatable接口呢,和 直接做一個屬性不是一樣嗎?這個問題問的非常的好,確實既然魚不能夠決定自己能不能吃、好不好吃,那麼爲什麼魚要實現IEatable接口呢。其實,在 Fish上實現IEatable接口完全是出於使用方便性和接口的層次(後續的文章中會重點討論這個問題)來考慮的, 完全面向對象的搞法應該是有另外一個對象來鑑定這個魚是否能吃、好不好吃的(這也是基於設計的平衡來考慮的,可以參看開放-封閉原則)。在這個地方使用接 口和屬性本質上沒有什麼差別,但是一旦鑑別魚能不能吃、好不好吃的鑑別方式(實現方法)發生變化的時候,使用屬性的方式就難以擴展了,只能修改代碼了,但 是使用接口的好處是我可以使用其它的方式補救,例如做一個實現IEatable接口的裝飾對象來裝飾魚對象。
    另外,導致需要魚對象實現IEatable接口的原因可能是出於接口隔離原則的考慮,如果使用屬性來辨別魚是否能吃,必然使用的地方就依賴魚對象了,提高了系統的耦合性。示意代碼如下:

 1 '檢索是否可以吃的食物
 2 Public Function GetEatableFish(ByVal foods As IEatable()) As IEatable()
 3 
 4     '用於保存列表
 5     Dim tempList As New ArrayList
 6 
 7     '循環的檢索
 8     For Each item As IEatable In foods
 9 
10         '判斷是否可以吃
11         If item.IsEatable Then
12 
13             tempList.Add(item)
14         End If
15     Next
16 
17     '返回結果
18     Return tempList.ToArray(GetType(IEatable))
19 
20 End Function
21 
22 '是否可以吃接口
23 Public Interface IEatable
24 
25     '是否可以吃
26     Function IsEatable() As Boolean
27 
28 End Interface

   軟件設計的時候沒有一味的好,也沒有一味的差,任何事情都有其兩面性,這個是需要取捨的,我們能夠做到的事情就是讓設計可控,如果設計失控了,那就全部完 蛋了。話說回來,如果能夠確認當前的系統中評判魚能不能吃的標準不會發生改變,把這個不會發生改變的東西集成到魚對象中是完全可以的,在具體的實現上用屬 性來實現也是一個非常不錯的搞法。

  • 來自名爲    Anders Liu    的評論

嗯。。。建議你在多想想再繼續寫。

比如這個:
public class Goby : IFish, IClimbable, IEatable
我認爲這樣比較好:
public class Goby : Fish, IClimbable, IEatable

看到區別了麼? 

    至於Anders Liu 的評論應該與wanghualiang 的意見基本上是一致的,如果我沒有理解錯誤的話。我們引入一個Class的時候需要考慮的是引入這個Class的目的,如果沒有任何目的的引入一個類或者是僅僅簡單的爲了封裝一個方法來引入一個類是不可靠的,後面我會寫一篇隨筆來專門討論類和接口。

轉載地址:http://www.cnblogs.com/zengezenge/archive/2007/08/01/838812.html


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章