Я хочу задать вопрос о том, как вы подходите к простой объектно-ориентированной проблеме проектирования. У меня есть несколько собственных идей о том, какой лучший способ решить этот сценарий, но мне было бы интересно услышать некоторые мнения сообщества Stack Overflow. Также приветствуются ссылки на соответствующие онлайн-статьи. Я использую C#, но вопрос не зависит от языка.Объектно-ориентированные рекомендации - Наследование v Состав v Интерфейсы
Предположим, что я пишу видеомагазина приложение, у которого база данных имеет Person
таблицу, с PersonId
, Name
, DateOfBirth
и Address
полей. Он также имеет таблицу Staff
, которая имеет ссылку на PersonId
и таблицу Customer
, которая также ссылается на PersonId
.
Простой объектно-ориентированный подход должен был бы сказать, что Customer
«является» Person
и, следовательно, создавать классы немного как это:
class Person {
public int PersonId { get; set; }
public string Name { get; set; }
public DateTime DateOfBirth { get; set; }
public string Address { get; set; }
}
class Customer : Person {
public int CustomerId { get; set; }
public DateTime JoinedDate { get; set; }
}
class Staff : Person {
public int StaffId { get; set; }
public string JobTitle { get; set; }
}
Теперь мы можем написать функцию сказать, чтобы отправить электронную почту для всех клиентов :
static void SendEmailToCustomers(IEnumerable<Person> everyone) {
foreach(Person p in everyone)
if(p is Customer)
SendEmail(p);
}
Эта система работает нормально, пока у нас нет человека, который является одновременно клиентом и сотрудником. Если предположить, что мы действительно не хотим, чтобы наш everyone
список, чтобы иметь один и тот же человек, в два раза, один раз как Customer
и один раз как Staff
, мы делаем произвольный выбор между:
class StaffCustomer : Customer { ...
и
class StaffCustomer : Staff { ...
Очевидно, что только первая из этих двух не нарушит функцию SendEmailToCustomers
.
Итак, что бы вы сделали?
- Сделать
Person
класс есть дополнительные ссылки наStaffDetails
иCustomerDetails
класса? - Создайте новый класс, который содержит
Person
, а также дополнительныеStaffDetails
иCustomerDetails
? - Сделать все интерфейсом (например,
IPerson
,IStaff
,ICustomer
) и создать три класса, в которых реализованы соответствующие интерфейсы? - Возьмите другой совершенно другой подход?
Да, и вы можете выбрать одну реализацию сейчас и передумать позже, не нарушая при этом другой код. – 2008-10-19 15:33:14