1

最近我在一次採訪中被問到設計一個鳥類飛行模擬器的問題。 我繼續思考模擬器類的策略模式和空氣壓力,風速等屬性。一種方法將採用鳥類物體和時間,並返回x,y,z座標。 例如對象Orient設計爲什麼我們需要Bird類的組合?

class Simulator 
attr_accesor :bird, :air_pressure, :wind_velocity 

def map_coordinates(bird, time) 
    ... 
end 
... 
end 

,然後想到鳥類:

在鳥能飛/飛不起來的屬性我想過這會在初始化時設定一個布爾變量。對於e.g:

class Bird 
attr_accessor :weight, :wing_dimension, :canfly, :height.... 

def initialize(weight, wing_dimension, canfly, height) 
    @weight = weight 
    @wing_dimension = wing_dimension 
    @canfly = canfly 
    @height = height 
end 
end 

我的問題是從的觀點OOD點,它說鳥類應該使用成分和使用一個類來封裝在一個類所需要的屬性。 https://www.safaribooksonline.com/library/view/head-first-design/0596007124/ch01.html

那麼,我真的需要一個類來映射can behavior行爲嗎?在創建Bird對象時,在這種情況下,我不能只是初始化一個布爾型字段。

爲什麼這不是一個好設計? 如果不是,最好的方法是什麼,爲什麼?

+0

爲什麼飛行模擬器會執行一個不能飛的鳥? – jaco0646

+0

確實!但面試官問了這個問題......你如何製作一隻不能飛的鳥雞的物體 –

+0

http://stackoverflow.com/questions/49002/prefer-composition-over-inheritance – jaco0646

回答

1

就OOD而言,重要的是要對關聯/聚合,繼承,組合和使用進行比較。在構圖關係中,類應該使用類的方法新的來創建對象實例。

鳥類具​​有相關的特定重量和高度,就成分而言,鳥類具有兩個翅膀和一個峯值,其可以是不同的類別。在Wing類中,wing_dimension屬性應該作爲聚合關係包括在鳥類的體重和身高中。

class Bird 
attr_accessor :weight, :height, :rightWing, :leftWing, :peak 

def initialize(weight, height) 
    @weight = weight 
    @height = height 
    rightWing = Wing. new 
    leftWing = Wing. new 
    peak = Peak.new 
end 
end 

在模擬器類中,例如,如果您想要設計飛行模擬器,則此屬性在不同的類中需要通用。總而言之,如果在一般類(例如「動物」)與鳥類和蒼蠅(昆蟲)之間存在繼承關係,那麼可以在deg中建立聚合關係,並且可以作爲動物類的馴服。

class Simulator 
attr_accesor :animal, :air_pressure, :wind_velocity 

def map_coordinates(animal, time) 
    ... 
end 
... 
end 
1

所以,我真的需要一個類來映射canfly行爲?在創建Bird對象的情況下,在這種情況下,我不能只是初始化布爾字段嗎?

爲什麼這不是一個好的設計?如果不是,最好的方法是什麼,爲什麼?

對於你的第一個問題:「我真的需要......嗎?」這是一個真的好 的問題。在面向對象的設計方面,這是你需要問自己的問題。事實上,這正是設計決策做得如何。

事實上,你也到達了一個試探性的解決方案「我不能只是......?「意味着你已經確定ONE,你可能有一個二進制的解決方案解決小問題布爾canfly真:?假

假設,你已經看了看大圖你能想象你的。」模擬器「將所有不同種類的鳥,甚至鳥類 不能飛,以及那些典型鳥事。

最後,你在其他三個,真是太棒問題到達。
我可以沒有幫助,但想知道是否不是你直接從OOA & D教科書中提出這些問題。

1)爲什麼這不是一個好的設計?

2)什麼是更好的設計?

3)爲什麼會第二設計比第一

可以更好,我要在這裏盡我所能。我將試圖從中提出你的方法來解答這些問題,並且以你所做的方式進行說明。看看纖巧佔板面積,所有的這些問題在這裏做,相較於巨大的腳印WILL使我的帖子,試圖填補所有空白的,因爲你不知道有多少解答這些問題可能會產生(也不會)。那恰好是一個的答案。男人,我希望這不會變成一個龐大的混亂。(這是另一個)

我首先想到,我想澄清一個非常重要的區別。
這些問題的性質不同於您希望在代數教科書中找到答案的問題的性質。代數約爲如何。我發現WHY
在代數計算之前並不代表任何代數。

爲什麼不是這樣...... 什麼方式,我應該...... 這是怎麼回事方式更好...... 爲什麼是更好的方式...? 爲什麼我應該甚至在乎嗎? 這些是你在哲學教科書中找到答案的種類。它們是OOD的適當類型,因爲OOD更像是一種哲學,而不是「軟科學」。這是我的看法,其他人持這種觀點,但有些人認爲不然。這是否聽起來混凝土

有趣的是,這是一個在OOD中用來區分派生類與抽象類或接口的術語。這是結果,但它是不是的設計。在我看來,首先要理解的是,如果不是更多,首先要比任何設計都同等重要,有些人可能會試圖作爲一個很好的答案來傳遞。

讓我再問一個問題。您是否希望在您的代碼庫中有微小的佔用空間,或者您的代碼庫中是否有巨大的佔用空間?因爲你可以做你想做的事,那是你的選擇。但是,讓我指出一些可能會改變你的想法的東西。我可以創建一個接口讓我們說,我可以稱它爲這樣的東西,我

public Interface IEveryPossibleFlyingOperationYouOrAnyoneElseMightImagine {};你可能會說:這是一個可笑的漫長而又過時的描述性命名約定!我會回覆:是的,但你甚至無法想象Interface會覆蓋多少東西。 ... 再說,我只需要編寫一次,因爲那樣的話,我可以做到這一點...
IEveryPossibleFlyingOperationYouOrAnyoneElseMightImagine飛;
然後,我會在我的代碼庫中放上那個小小的fly(也是一種正好碰巧飛過的昆蟲)。然後,我會關閉它,並且HOPEFULLY永遠不必再打開它。此外,爲了將來可能的擴展目的,屬於那個你不知道的界面的所有東西,因爲它已經被抽象出來,與其他類似的東西松散地結合在一起,以便將來可能擴展,永遠不會破壞你的代碼庫。它怎麼可能?這是一隻小小的蒼蠅。

你會看到這個答案是多久,它只是劃痕表面你真正問的問題在這裏我向你保證。

現在,我會嘗試給你一些更具體的東西,儘管它不足以滿足你在這裏問的所有問題。

面向對象通常是關於很多事情,我希望至少有一些意義,這一點是一個原則。如果學習和遵循這個原則,你將永遠不會在你的代碼庫中留下足跡。

這個接口背後的大祕密是你的客戶永遠不會知道的東西,但我向你保證,它被放在一起的方式使它非常靈活和適應性強,因爲我根據嘗試和證明的原則和模式,其他人比我更聰明。

即使他們不知道這種範例的所有可能性,因爲有太多的數量。他們根本不在乎,因爲他們通過混合和匹配原則和模式來解決其他設計問題,非常簡單地解決了真正複雜的問題。

另外,得到這個,下一次你開始設計一些東西,你可以把那隻小小的蒼蠅放在那裏,並在那裏使用它,而且永遠只會有一個地方去維護和改進所有在那隻小小的蒼蠅後面。

我知道這可能不是你正在尋找的答案,或者你已經得到它,這將是非常棒的。我花了很長時間才弄清楚什麼是對象,甚至是......但一旦它點擊了,在一位非常聰明的教授的幫助下,他向我展示了我試圖在這裏展示的東西;噢.. 和一本叫做四人幫的書;那麼我就可以開始了,我只希望我也能理解。

我想如果你回頭看看那篇文章,你將能夠弄清楚其他答案是什麼,我只回答了簡單的問題(或者嘗試過)。我看了看,所有的信息都在那裏。這可能是因爲你只需要以一種稍微不同的方式來看待它,但如果你真的想知道的話,你會得到它。

我很抱歉,但這是我能做的最好的事,同時也是誠實的。如果有人試圖告訴你如何是答案,而不是爲什麼,不要聽他們,因爲可能不理解它,但不是因爲它很難。那將是因爲他們沒有開始提出像你這樣的正確問題。我希望你很好,希望有其他人能出現,他們可以比我更好地解釋它。 +1)詢問所有正確的問題!

相關問題