簡體   English   中英

是否使用has-a(組合)或is-a(繼承)來建模汽車對象(及其部件,如引擎)?

[英]Whether to model a car object (and its parts such as engine) with has-a (composition) or is-a (inheritance)?

我正在開發一個包含Car對象的類庫。

困境是,汽車本身將是一個類別,如注冊號碼和汽車的其他一般信息。

但是汽車有發動機,底盤等。這些物體也需要建模。 它們應該是嵌入汽車的課程嗎? 如果沒有,嵌入式類的使用場景是什么?

我已經知道組合是“的一部分”,所以你可以模擬單獨的類並使用引擎類型,例如,在汽車的現場級別來實現這一點。 然而,“聚合”,其與在ctor中傳遞的類型“具有”關系,也適用(汽車“具有”引擎)。

我該走哪條路?

編輯:我目前正在做作業因此缺乏回復。 該類庫適用於基於汽車的Web應用程序。 我是一名專業的開發人員(我以.NET開發為生,但作為一名大三學生)所以這不是一個功課問題。

謝謝

這真的取決於你的應用程序。

例如,您可以將輪子實現為單獨的類,包含有關輪胎在哪個輪胎上的信息,磨損程度等等,但如果您的應用程序甚至不關心輪子,則整個課程都是浪費代碼。

我可以看到三個組合用例:

  • 擁有的班級變得過於復雜,應該被打破。
  • 擁有類具有一組可以映射到類的屬性的多個副本。 這允許您將所有這些屬性綁定在一起。
  • 包含的對象可能需要與擁有它的對象分開進行檢查或考慮(例如,您可能希望將Engine對象移動到另一個車輛),或者可以將其替換為單個單元。

總結:使用組合作為封裝復雜性或消除重復的工具。 如果它不能用於其中一個目的,那么可能不值得為它做一個新課程。

一個類應該盡可能少地承擔責任,並將其他功能封裝並委托給其他類。 許多做一件事的小而簡單的類是可讀,穩定的代碼庫的標志。

是的,一輛汽車將“擁有”一個引擎,但我建議使用一個接口,類似的“有”關系。 再次,取決於教授,你可能會獲得獎勵積分讓工廠創建不同的汽車(適當,不?):

public class Car
{
    private Engine engine;
    public Car(Engine engine)
    {
        this.engine = engine;
    }

    public void accelerate()
    {
        this.engine.goFaster();
    }

    public void decelerate()
    {
        this.engine.goSlower();
    }

}

public interface Engine
{
    public void goFaster();
    public void goSlower();
}


public class ReallyFastEngine implements Engine
{
    public void goFaster()
    {
    // some code that goes really fast
    }
    public void goSlower()
    {
    // some code that goes slower
    }    
}

public class NotAsFastEngine implements Engine
{
    public void goFaster()
    {
    // some code that goes not as fast
    }
    public void goSlower()
    {
    // some code that goes slower
    }    
}

public class CarFactory()
{
    public static Car createFastCar()
    {
         return new Car(new ReallyFastEngine());
    }

    public static Car createNotAsFastCar()
    {
         return new Car(new NotAsFastEngine());
    }
}

看作是家庭作業,並且根據您的導師/教授/老師的傾向,您可能最好沿着為引擎,車輪等編寫單獨的課程的路線。 即使它可能完全過度設計,並且您的應用程序可能不關心它們,但您的作業可能會標記為以下標准:

“他們確定了發動機艙”

“它有像Start()這樣的合理方法”

“將它們標記為將所有內容集中在一個實際上更簡單的大類中,因為它們顯然不理解組合”

或者其他什么,而不是這個線程中更務實的人適用於他們自己的設計的那種標准。

只將汽車模型分解為可以作為汽車范圍之外的單獨實體暴露的碎片。 考慮它的另一種方法是,當你轉動鑰匙時,你真的了解你的汽車是如何開始的嗎? 就典型的駕駛員而言,引擎蓋下的一切都是一個大而且嘈雜的黑匣子。 汽車工程師知道汽車所有者需要維護的常見零件,並明確地設計它們以用於不同級別的用戶交互,例如油尺或冷卻液儲液器補充蓋。

你能模仿汽車的每一塊嗎? 當然。 對各個火花塞進行建模是否有幫助? 可能不是。

您是否需要具有不同屬性(如顏色或尺寸)的汽車? 您是否需要具有乘客或牽引能力等不同能力的汽車? 一個不同的地方是你需要不同行為的汽車。 這是你真正需要考慮對具有屬性的Driver對象進行建模的地方,從簡單的反應時間到復雜的反應時間。

將車輛建模為面向對象或繼承的示例是有問題的,因為這些示例並未真正解釋定義類的基本屬性之間的真正區別。 這對StackOverflow來說並不陌生,但這個問題也不重復, 請參閱此SO線程 我和我的一個朋友進行了同樣的討論,並在我的博客上發布了一個日志 閱讀FAA認可的不同飛機類型以及每種類型的規定如何細分。 有許多不同類型的飛機,最大的分離是動力和無動力之間。

查看FAA使用定義

飛機是指用於或打算用於在空中飛行的裝置。

飛機是指比空氣重的發動機驅動的固定翼飛機,通過空氣對其機翼的動態反應在飛行中支撐。

飛艇是指可以轉向的發動機驅動的輕於空氣的飛機。

還有比空氣輕且比空氣重的空氣。 熱氣球無動力且比空氣輕。 飛艇是動力的,比空氣輕。 滑翔機無動力且比空氣重。 波音757的動力比空氣重,但增加了另一類“固定翼”,這與直升機不同,直升機也是動力的,比空氣重,但是是“旋轉翼”。

這是表格形式的前四個:

                 |  Powered   |    Unpowered
---------------------------------------------------
Lighter-than-air |  Blimp     |    Hot-air balloon 
Heavier-than-air |  737       |    Glider

你得到了照片。

你不能只說你將發動機與汽車分開建模,因為沒有發動機的汽車可能是一個完全不同的動物。 沒有發動機的汽車就像拖車一樣,也沒有發動機,但也沒有發動機。 在這些情況下,'is-a'和'has-a'都不適合我們構建對象的具體方式。 你沒有宣稱飛艇是一架“比空氣更輕”的飛機,所以它是一個熱氣球。 除了他們利用的物理學之外,它們都比空氣更輕的事實並沒有使它們以任何方式相關。 區別很重要,因為適用的規則和規定是不同的。 從另一個角度來看,我們並沒有將飛艇描述為具有“發動機”的熱氣球。 飛機沒有物理關系,這種關系是應該如何處理的。

如果您不需要將對象定義到該詳細程度,則可能不需要將它們建模到該詳細級別。

汽車將是一個頂級的對象。 包括數字,ID或描述等簡單字段。 並且會有像Engine這樣的復雜字段,它本身就是一個對象。

所以汽車看起來像:

class Car{
     String ID;
     Engine engine;
}

這是一種關系。

您可以決定引擎,Chasis等類的一個標准。
需要作為內部類(嵌入類)存在是否是實例
這些類可以在您的應用程序的其他地方使用。 在這種情況下
決策很簡單,就是讓這些類分開存在
(不是內部類)。

即使這些類沒有在你的應用程序中的其他地方使用,
標准可以是可測試性。 將這些類嵌入到內部和您的
設計是否可以進行單元測試,可以適當地測試你的
代碼提供良好的覆蓋范圍。

例如,如果你已經創建了一個引用一個的實例變量
引擎對象和此變量正在Car.And的構造函數中初始化
您的Engine類有一些需要測試的方法。 那怎么可能呢
你添加單元測試來檢查Engine類中的代碼? 可能你會的
在Car類中有一些暴露行為或Engine類允許的方法
你要編寫單元測試。 那么問題是是否需要揭露
Engine類的行為不會比Engine類更好
它自己站着?

或者,可能不需要明確地測試方法
Car中的方法的引擎類和單元測試引擎類代碼
同樣。 然后它反映了Engine類與Car類的緊密集成
並且意味着它可以保持為內在階級。

這取決於你想要做什么。 試圖在不知道用例的情況下設計一個“汽車”類(或任何其他類)是徒勞的。

您將根據您嘗試啟用的用例,以非常不同的方式設計類及其關系和交互。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM