Note that there are some explanatory texts on larger screens.

plurals
  1. POObject Oriented Best Practices - Inheritance v Composition v Interfaces
    text
    copied!<p>I want to ask a question about how you would approach a simple object-oriented design problem. I have a few ideas of my own about what the best way of tackling this scenario, but I would be interested in hearing some opinions from the Stack Overflow community. Links to relevant online articles are also appreciated. I'm using C#, but the question is not language specific.</p> <p>Suppose I am writing a video store application whose database has a <code>Person</code> table, with <code>PersonId</code>, <code>Name</code>, <code>DateOfBirth</code> and <code>Address</code> fields. It also has a <code>Staff</code> table, which has a link to a <code>PersonId</code>, and a <code>Customer</code> table which also links to <code>PersonId</code>.</p> <p>A simple object oriented approach would be to say that a <code>Customer</code> "is a" <code>Person</code> and therefore create classes a bit like this:</p> <pre><code>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; } } </code></pre> <p>Now we can write a function say to send emails to all customers:</p> <pre><code>static void SendEmailToCustomers(IEnumerable&lt;Person&gt; everyone) { foreach(Person p in everyone) if(p is Customer) SendEmail(p); } </code></pre> <p>This system works fine until we have someone who is both a customer and a member of staff. Assuming that we don't really want our <code>everyone</code> list to have the same person in twice, once as a <code>Customer</code> and once as a <code>Staff</code>, do we make an arbitrary choice between:</p> <pre><code>class StaffCustomer : Customer { ... </code></pre> <p>and </p> <pre><code>class StaffCustomer : Staff { ... </code></pre> <p>Obviously only the first of these two would not break the <code>SendEmailToCustomers</code> function.</p> <p>So what would you do? </p> <ul> <li>Make the <code>Person</code> class have optional references to a <code>StaffDetails</code> and <code>CustomerDetails</code> class? </li> <li>Create a new class that contained a <code>Person</code>, plus optional <code>StaffDetails</code> and <code>CustomerDetails</code>? </li> <li>Make everything an interface (e.g. <code>IPerson</code>, <code>IStaff</code>, <code>ICustomer</code>) and create three classes that implemented the appropriate interfaces? </li> <li>Take another completely different approach?</li> </ul>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload