2

I'm creating an UML class diagram but I'm totally stuck on the relation between employee, customer and person. The requirements ask to store data of employees and customers, which they should be a sub-class of the abstract class 'Person'; the problem is that the employee could be also a customer. How should I handle such requirement?

enter image description here

Christophe
  • 68,716
  • 7
  • 72
  • 138
Ale__ssio
  • 83
  • 7
  • 1
    Inheritance isn't the solution to everything. If you have that situation you could model just person and have compositions for customer and employee which can be added single or both at all. https://en.wikipedia.org/wiki/Composition_over_inheritance – qwerty_so Jan 14 '22 at 22:37
  • So you mean that in such case I should not use the abstract class 'Person' even if Employee and Customer share some attributes as name,surname? – Ale__ssio Jan 14 '22 at 22:44
  • Exactly so. Read the Wiki... – qwerty_so Jan 14 '22 at 22:46
  • Somehow your first comment was cutted and I didn't see the link, thanks! In case I'd need to add another class Company which could be a customer? I'd need to implement the class Customer and have composition for Company, Person and employee right? In such case the customer could include the company or the customer or the employee, but in this situation how should I connect the customer to the person? Can I create one inheritance between person and employee only? – Ale__ssio Jan 14 '22 at 23:40
  • Sure you can. But it's always hard to tell which design is the best. It's basically a matter of experience. – qwerty_so Jan 15 '22 at 09:53

1 Answers1

2

As the discussion in the comments shows, there are two sides to this problem: the theoretical and the practical one

Solution with inheritance - theoretical approach

A popular (wrong) belief is that Employee and Customer both are Person: they share all the characteristics and features of a human being, i.e. they have names, addresses, feelings, moods, blood pressure, etc. This is probably why, so many academics, trainers, or tutorials give funny OOP examples and exercises with exactly these classes:

The requirements ask to store data of employees and customers, which they should be a sub-class of the abstract class 'Person'

How to solve it? Exactly like you did: put in Person the common attributes, associations and operations. Put in Employee and Customer the specific ones. You just need to resolve the ambiguity on Type that is redefined in Customer, and it seems to be different types that may coexist.

In UML, this is all you need, because classification (i.e. viewing objects as instance of a class) is dynamic. So an employee that is a client is fully covered by your model, by just taking a different point of view on the same object at a different moment in time. The full explanation here on StackOverflow.

Implement this UML solution in a programming languages won't unfortunately work as simple, since most programming languages require to choose the class of an object at birth, and it will remain unchangeable up to the death of an object. If you want to solve this with inheritance at all cost, you could imagine to add a class EmployeeCustomer that would just inherit from both Employee and Customer. I would not advise such a solution because it relies on multiple inheritance,and if later you add classes such as Visitor and Supplier, you'd end up with a lot of unnecessary classes. You can nevertheless find a full analysis here on StackOverflow for a question related to a theoretical exam.

Solution with composition - practical approach

In the real world, the innocent starting assumption appears to be plain wrong. Because a customer can also be a company. Even in a supermarket. This is why in some countries, people can say at the cash-desk that they represent a company and need an invoice with VAT instead of a simple receipt.

In fact, Persons are Persons. Employee is just a role that a Person can have at a moment in time. And Customer is another role, a little more complex since companies cans also take such a role. This is of course much more complex to model, and does not really allow for inheritance.

Moreover, abusing of inheritance increase the risk of multiple inheritance. This is not a problem in itself, but only few languages really support it and many programmers get confused with it. This is why, there is a rule of thumb which says: Prefer composition over inheritance (keeping in mind that this refers to object composition and not UML composition)

You would implement this by just replacing the inheritance by an association. So a Customer would be associated to a Person, and would forward any person-specific operation to it. Same for Employee. A more powerful and flexible model would be to associate Person with multiple Role, and let Customer and Employee inherit from Role.

Christophe
  • 68,716
  • 7
  • 72
  • 138