Я хочу задать вопрос о том, как вы подходите к простой объектно-ориентированной проблеме проектирования. У меня есть несколько собственных идей о том, какой лучший способ решить этот сценарий, но мне было бы интересно услышать некоторые мнения сообщества 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) и создайте три класса, в которых реализованы соответствующие интерфейсы? - Возьмите другой совершенно другой подход?