Je veux poser une question sur la façon dont vous aborderiez un simple problème de conception orientée objet. J'ai quelques idées personnelles sur la meilleure façon d'aborder ce scénario, mais je serais intéressé par les opinions de la communauté Stack Overflow. Les liens vers des articles en ligne pertinents sont également appréciés. J'utilise C#, mais la question n'est pas spécifique au langage.
Supposons que j'écrive une application de vidéothèque dont la base de données comporte un fichier de type Person
table, avec PersonId
, Name
, DateOfBirth
et Address
champs. Il dispose également d'un Staff
qui contient un lien vers une PersonId
et un Customer
qui renvoie également à PersonId
.
Une approche orientée objet simple consisterait à dire qu'une Customer
"est un" Person
et donc de créer des classes un peu comme ceci :
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; }
}
Maintenant, nous pouvons écrire une fonction dire pour envoyer des emails à tous les clients :
static void SendEmailToCustomers(IEnumerable<Person> everyone) {
foreach(Person p in everyone)
if(p is Customer)
SendEmail(p);
}
Ce système fonctionne bien jusqu'à ce que nous ayons quelqu'un qui soit à la fois un client et un membre du personnel. En supposant que nous ne voulons pas vraiment que notre everyone
liste d'avoir la même personne deux fois, une fois en tant que Customer
et une fois en tant que Staff
faisons-nous un choix arbitraire entre.. :
class StaffCustomer : Customer { ...
et
class StaffCustomer : Staff { ...
De toute évidence, seul le premier de ces deux cas n'enfreindrait pas les règles de l'UE. SendEmailToCustomers
fonction.
Alors, que feriez-vous ?
- Faites le
Person
ont des références facultatives à une classeStaffDetails
etCustomerDetails
classe ? - Créer une nouvelle classe qui contient un
Person
plus optionnelStaffDetails
etCustomerDetails
? - Faire de chaque chose une interface (par exemple
IPerson
,IStaff
,ICustomer
) et créer trois classes qui implémentent les interfaces appropriées ? - Adopter une autre approche complètement différente ?