-1

I have the following UML class diagram in a C++ context. I want to make sure that a Customer can have only one role:

enter image description here

Can the Customer now only assume one role, and what does <<abstract>> have to do with this restriction? Do I even need to make customerRole abstract in this case?

6
  • Which language are you using? Some languages support multiple inheritance, which changes the answer. Jan 17, 2022 at 17:15
  • Hi, im using C++.
    – Seonix
    Jan 17, 2022 at 17:21
  • Please add that information to your question. Jan 17, 2022 at 17:21
  • Basically, are you asking if there is a way to guarantee a class only has one derived class? Jan 17, 2022 at 17:25
  • yes, especially if i need abstract in this case.
    – Seonix
    Jan 17, 2022 at 17:29

2 Answers 2

1

What does the diagram mean?

This UML design ensures that the Customer has 1 and exactly 1 CustomerRole, but that the instances of that role must be one of its specialization Recipient, Participant or Prospect.

You could further clarify that the relevant specializations are all in the diagram, using a generalization set and {disjoint,complete}:

enter image description here

Is the abstract CustomerRole needed?

In UML, an abstract class is a class that cannot be directly instantiated. This means that every instance of the CustomerRole shall be an instance of one of its specializations. If that class would not be abstract, an unspecialized CustomerRole could be allowed. By the way, «abstract» is not standard UML even if the notation is popular (see this answer on SO).

Without CustomerRole at all, it would be much more difficult to tell that there is only one single role:

  • Customer would need 3 associations 0..1, as well as a constraint to guarantee that exactly only one of the 3 associations is active for each instance.
  • If other kind of roles would be added later on, you'd need to add more such associations, thus modifying Customer, which makes that alternative design difficult to extend (the contrary of the Open-Closed Principle)

Are there other alternatives ?

An alternative UML design would be to make CustomerRole an «interface» and make Recipient, Participant and Prospect independent classes that realize this interface:

enter image description here

It is not possible to advise you to use the one or the other without knowing anything about the class features (aka the members in C++). The advantage of interfaces is less coupled classes. Interfaces are natively supported by many languages , whereas abuse of abstract classes could lead to more complex scenarios with multiple inheritance, something that is more difficult to deal with and supported in only a few languages (fortunately for you, C++ is among them).

3
  • So, without the abstract a customer could just be a customer?
    – Seonix
    Jan 17, 2022 at 21:56
  • @Seonix No, without «abstract», the class CustomerRole could be instantiated. This means that objects of that class could be directly created, and customer could "assume"/"have" a role CustomerRole, which would be different from the 3 other specialised role, and this seems not correct. Abstract prohibits the direct creation of a CustomerRole: you could have objects that correspond to a customerrole, but they would be necessarily one of the 3.
    – Christophe
    Jan 17, 2022 at 22:48
  • @Seonix In other words, when a class is abstract, "it has no direct instances: every instance of the abstract Classifier shall be an instance of one of its specializations" (wording of the UML specifications). By the way, a minor syntactic issue in the diagram: «abstract» although popular for historical reason is not completely correct. Abstract classes are indicated by puting their name in italic, or, if this is not possible with the {abstract} adornment after its name. See here for all the details: stackoverflow.com/q/46049761/372342
    – Christophe
    Jan 17, 2022 at 23:15
3

I think you are misunderstanding something here. Customer is not an abstract class. Instead, a "Customer" has a reference to a "CustomerRole" object. There are three "CustomerRole" classes, but the "Customer" doesn't know / care which one it is using. "CustomerRole" is an abstraction and not a concrete class. "Abstraction" has nothing to do directly with abstract classes.

In C++, your three classes Recipient, Participant and Prospect would have a common baseclass "CustomerRole". That base class might be abstract, but doesn't really have to be. In other languages supporting interfaces, you would have an interface "CustomerRole", Customer would have a reference to a "CustomerRole" interface, and Recipient, Participant and Prospect would implement the interface.

2
  • Out of curiosity: in UML the abstraction is a dependency between two classifiers (section 7.7.3.3, "An Abstraction is a Dependency that relates two NamedElements or sets of NamedElements that represent the same concept at different levels of abstraction or from different viewpoints"), whereas a class can be abstract (section 9.2.3.2, "specifies that the Classifier is abstract, i.e., has no direct instances: every instance of the abstract Classifier shall be an instance of one of its specializations"), noted either in italic, or with the {abstract} adornment. Which one did you mean?
    – Christophe
    Jan 17, 2022 at 23:05
  • "CustomerRole is an abstraction and not a concrete class" In this context, "not concrete" is equivalent to "abstract" (both in semantical and syntactic terms). In reality, CustomerRole is most likely going to be an abstract class since its only purpose is to serve as an abstraction for concrete roles. You are correct that not every abstraction inherently needs an abstract class; but in OP's particular case the abstraction in focus does warrant the use of an abstract class.
    – Flater
    Jan 19, 2022 at 10:16

Not the answer you're looking for? Browse other questions tagged or ask your own question.