UML Class Diagram - Two abstract classes?

Viewed 452

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

1 Answers

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.

Related