Дизайн класса для хранения нескольких экземпляров других классов - PullRequest
0 голосов
/ 31 мая 2011

Как вы проектируете класс, который может содержать экземпляры других классов. Я постараюсь объяснить. Customer экземпляр класса для каждого нового клиента. Клиент покупает автомобили, а затем выполняет определенные операции для каждого автомобиля. Например,

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

Нет операций, специфичных для любого автомобиля. Я думаю, что, может быть, существует способ создания класса Car при вызове метода buy(). Как правильно разработать класс для этого? Если есть другой путь, по которому я должен идти, пожалуйста, дайте мне знать.

Ответы [ 6 ]

2 голосов
/ 31 мая 2011

Самый простой способ - создать базовый класс для разных типов автомобилей.Все ваши конкретные автомобили (Mercedes, BMW) будут происходить из этого.Используя общий базовый класс или интерфейс, ваш класс Customer может работать с определенными автомобилями, не понимая их конкретно.

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 (по умолчанию).

Например, возможно, для Mercedes изменение цвета означает, что вы должны приобрести специальные шины.

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 или как-то еще).Вам также не нужны волшебные струны, такие как «Мерседес», так как вы можете где-нибудь ввести их неправильно.Но это основной шаблон проектирования, который может работать лучше всего.

1 голос
/ 31 мая 2011

Поскольку у вас нет операций, специфичных для какого-либо автомобиля, вам не нужно получать данные из Car. Предположим, что у вас есть класс Car, который имеет свойство Brand, которое является перечислением. Тогда вы можете создать свой класс Customer следующим образом:

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

Метод buy создаст новый экземпляр Car, установит его свойство Brand и добавит его к cars, переменной экземпляра Customer типа List<Car>.

Если вы уверены, что у клиента может быть только один автомобиль одной марки (нет клиента с двумя Mercededes? Может быть, 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();
}
1 голос
/ 31 мая 2011

Вторая форма, без сомнения, превосходит первую.

Поскольку автомобили могут существовать независимо от их владельцев, вы должны иметь возможность создавать машины без клиентов. Возможно, вы сможете добавить операции к Клиенту, чтобы добавить новую машину и получить уже существующие. Вы также можете приобрести автомобиль по VIN, а не по марке. Любой клиент может иметь более одного BMW.

Методы changeColor и changeTyres должны существовать в вашем объекте Car, а не в объекте customer.

Car bmw = carFactory.create("BMW");
customer.add(bmw);
Car bmwAgain = customer.get(bmw.Vin);
bmwAgain.changeColor("black");
1 голос
/ 31 мая 2011

Вы хотите композицию.Вы можете иметь общий список Car s и получать к ним доступ оттуда.

Если нет никаких операций, специфичных для какого-либо конкретного автомобиля, тогда у вас просто будут свойства "Make" и / или "Model".из автомобилей.

0 голосов
/ 31 мая 2011

ОК, это звучит немного как домашнее задание, но:

, если у вас были предметы, которые можно было купить, все они были автомобилями, то есть общие черты, такие как «сервис», «мот», «свет», «шины»"," выхлоп "," рисование "как предметы, которые вы затем" меняете "

У вас может быть базовый класс BaseCar, с которого вы потом спускаетесь, чтобы получить свой BWM / Merc и т. д.

С каждым клиентом у вас будет класс, в котором вы определяете предметы, которые нужно купить как базовую машину, но вы можете отправить им «новый Mercedes ()» и получить новый экземпляр фактической машины, которую они купили.

0 голосов
/ 31 мая 2011

Наследование фабрики - это то, что вам нужно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...