开发者

Design class to hold multiple instances of other classes

How do you design a class that can hold instances of other classes. I'll try to explain. A Customer class instance for every new customer. A customer buys cars and then does specific operations to each car. For example,

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

Can I do something like this:

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

There are no operations specific to any car. I'm thinking that maybe there is a way where a Car class is instantiated when buy() method开发者_运维百科 is called. What is the proper way to design a class for this ? If there is a different way I should go about this, please let me know.


The easiest way is to create a base class for the different types of cars. All your specific cars (Mercedes, BMW) will derive from this. By using a common base class or interface, your Customer class can operate on the specific cars without having any understanding of them specifically.

public abstract class CarBase
{
    private string _color;

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

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

You can then create specific types of cars:

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

    }

}

Because each method in CarBase is virtual, each specific implementation can offer up it's own implementation if it needs, otherwise it just relies on the 'default' ChangeTires().

For instance, perhaps with Mercedes, changing the color means you must get special tires.

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

You can then supply a method for Customer that adds a new vehicle.

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();
    }
}

You can then do things like:

Customer c = new Customer();

c.BuyCar("Mercedes");

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

There's better ways to manage the cars. You probably want to look at a factory for creating cars: http://www.dofactory.com/Patterns/PatternFactory.aspx

You probably also don't want a Dictionary of manufactures (i'd imagine you'd reference them by VIN or something). You also don't want magic strings like "Mercedes", since you might mis-type it somewhere. But this is the basic design pattern that might work best.


Since you don't have operations specific to any car, you don't need to derive from Car. Let's assume that you have a Car class that has a Brand property, which is an enum. Then you could design your Customer class like this:

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

The buy method would create a new instance of Car, set it's Brand property and add it to cars, an instance variable of Customer of type List<Car>.

If you are sure that a customer can only have one car of one brand (no customer with two Mercededes? Maybe an SLK for the weekend and an A for finding a parking spot in the city?), then you can define your interface like this:

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

Otherwise, I'd expose an enumeration of cars and use LINQ:

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


You want composition. You can have an generic list of Cars and access them from there.

If there are no operations specific to any particular car, then you would just have "Make" and/or "Model" be properties of the cars.


The second form is without a doubt superior to the first form.

Since cars can exist independent of their owners, you should be able to instantiate a car without a customer. Perhaps you can then add operations to Customer to add a new car, and get existing cars. You may also wish to get a car by VIN rather than make. Any one customer may own more than one BMW.

The changeColor and changeTyres methods should exist on your Car object instead of your customer object.

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


Inheritance an factory is what you need.


OK, this sounds a little like homework but:

if you had items to buy which were all cars, so had commonalities, such as "service", "mot", "lights", "tyres", "exhaust","paint" as items you would then be "changing"

You could have a base class of BaseCar, which then you descend from to get your BWM/Merc etc.

The with each customer, you would have a class where you define the items to buy as the base car, but you can send them the "new Mercedes()" and get a new instance of the actual car they bought.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜