繁体   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