簡體   English   中英

設計 class 以容納其他類的多個實例

[英]Design class to hold multiple instances of other classes

你如何設計一個可以容納其他類的實例的 class。 我會盡力解釋。 每個新客戶的Customer class 實例。 客戶購買汽車,然后對每輛汽車進行特定操作。 例如,

Customer c = new Customer();
// customer buys cars 
c.buyMercedes();
c.buyBMW();
// operations done on the car
c.changeMercedesColor();
c.changeBMWtyres();

我可以做這樣的事情:

Customer c = new Customer();
c.buy(Mercedes);
c.buy(BMW);
c.car("Mercedes").changeColor();
c.car("BMW").changetyres();

沒有特定於任何汽車的操作。 我在想也許有一種方法可以在調用buy()方法時實例化Car class 。 為此設計 class 的正確方法是什么? 如果有不同的方式我應該 go 關於這個,請告訴我。

最簡單的方法是為不同類型的汽車創建一個基礎 class。 您所有的特定汽車(梅賽德斯、寶馬)都將由此衍生。 通過使用通用基礎 class 或接口,您的客戶 class 可以對特定汽車進行操作,而無需具體了解它們。

public abstract class CarBase
{
    private string _color;

    public virtual void ChangeTires()
    {
         // do the default change tires
    }

    public virtual void ChangeColor(string _color)
    {
         _color = color;
    }
}

然后,您可以創建特定類型的汽車:

public class Mercedes : CarBase
{
    public override void ChangeColor(string color)
    {

    }

}

因為 CarBase 中的每個方法都是虛擬的,所以如果需要,每個特定的實現都可以提供自己的實現,否則它只依賴“默認”ChangeTires()。

例如,也許對於梅賽德斯來說,改變顏色意味着你必須得到特殊的輪胎。

public class Mercedes : CarBase
{
    public override void ChangeColor(string color)
    {
         if (color == red)
             AddRacingTires();
    }
} 

然后,您可以為客戶提供添加新車輛的方法。

public class Customer
{
    public Dictionary<string, CarBase> OwnedCars { get; set; }

    public void BuyCar(string manufacture)
    {
        if (manufacture== "Mercedes")
           OwnedCars[manufactor] = new Mercedes();

        if (manufacture== "BMW")
           OwnedCars[manufactor] = new BMW();
    }
}

然后,您可以執行以下操作:

Customer c = new Customer();

c.BuyCar("Mercedes");

c.OwnedCars["Mercedes"].ChangeTires();

有更好的方法來管理汽車。 您可能想看看制造汽車的工廠: http://www.dofactory.com/Patterns/PatternFactory.aspx

您可能也不想要制造商詞典(我想您會通過 VIN 或其他東西來引用它們)。 您也不想要像“Mercedes”這樣的魔術字符串,因為您可能會在某處輸入錯誤。 但這是可能效果最好的基本設計模式。

你想要作曲。 您可以擁有Car的通用列表並從那里訪問它們。

如果沒有特定於任何特定汽車的操作,那么您只需將“制造”和/或“型號”作為汽車的屬性。

第二種形式無疑優於第一種形式。

由於汽車可以獨立於其所有者而存在,因此您應該能夠在沒有客戶的情況下實例化汽車。 也許您可以向客戶添加操作以添加新車並獲取現有汽車。 您可能還希望通過 VIN 而不是制造來獲得汽車。 任何一位客戶都可能擁有不止一輛寶馬。

changeColor 和 changeTyres 方法應該存在於您的 Car object 而不是您的客戶 object 上。

Car bmw = carFactory.create("BMW");
customer.add(bmw);
Car bmwAgain = customer.get(bmw.Vin);
bmwAgain.changeColor("black");

由於您沒有特定於任何汽車的操作,因此您不需要從 Car 派生。 假設您有一個Car class 具有Brand屬性,這是一個枚舉。 然后您可以像這樣設計您的客戶 class:

Customer c = new Customer();
c.buy(Brands.Mercedes);
c.buy(Brands.BMW);

buy方法將創建一個Car的新實例,設置它的Brand屬性並將其添加到cars ,這是一個List<Car>類型的Customer的實例變量。

如果您確定客戶只能擁有一個品牌的汽車(沒有客戶擁有兩輛梅賽德斯?也許是周末的 SLK 和在城市尋找停車位的 A?),那么您可以像這樣定義您的界面:

c.getCar(Brands.Mercedes).changeColor();
c.getCar(Brands.BMW).changeTyres();

否則,我會公開汽車枚舉並使用 LINQ:

var mercedeses = c.Cars.Where(car => car.Brand == Brands.Mercedes);
foreach (var car in mercedeces) {
   car.changeTyres();
}

Inheritance 工廠就是您所需要的。

好的,這聽起來有點像家庭作業,但是:

如果您要購買的所有物品都是汽車,那么諸如“服務”,“汽車”,“燈”,“輪胎”,“排氣”,“油漆”之類的共同點也是您將要“改變”的物品

你可以有一個 BaseCar 的基礎 class,然后你從它下來得到你的 BWM/Merc 等。

對於每個客戶,您將擁有一個 class,您可以在其中將要購買的物品定義為基礎汽車,但您可以向他們發送“new Mercedes()”並獲得他們購買的實際汽車的新實例。

暫無
暫無

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

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