Я хочу задать вопрос о том, как вы подходите к простой объектно-ориентированной проблеме проектирования. У меня есть несколько собственных идей о том, какой лучший способ решить этот сценарий, но мне было бы интересно услышать некоторые мнения сообщества Stack Overflow. Также приветствуются ссылки на соответствующие онлайн-статьи. Я использую С#, но вопрос не зависит от языка.
Предположим, что я пишу приложение для хранения видео, база данных которого имеет таблицу Person
, с полями PersonId
, Name
, DateOfBirth
и Address
. Он также имеет таблицу Staff
, которая имеет ссылку на таблицу PersonId
и a Customer
, которая также ссылается на PersonId
.
Простым объектно-ориентированным подходом было бы сказать, что a 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
) и создайте три класса, в которых реализованы соответствующие интерфейсы? - Возьмите другой совершенно другой подход?