I am trying to create a system for managing vaccines against covid.
The system supports 3 different vaccines but each citizen can only get one and the system has to differentiate between the citizens who are older than 65, the AstraZeneca vaccine cannot be given to people older than that age.
Below I tried to create a basic UML class diagram. However I'm pretty sure I'm missing something since the vaccine should be also connected to the AstraZeneca class?
The diagram is confusing, since it only shows associations, but regrouping them in an unexpected manner. It looks more like a decision tree than a real class diagram.
First improvements you need to consider:
Pfizer BioNTech, Moderna and AstraZeneca are each a Vaccine: you should show this with a generalization from the specific vaccine to the general vaccine.
age 65+ seems not a good candidate for a class: in most OO languanges an object of a class keeps the class during its whole life. But citizen do not change class at 65. Age is a (derived) property of Citizen. The wording "astrazeneca vaccine cannot be given to people older than 65" moreover is an expression of a constraint.
Finally, if you manage vaccines, you need to manage also shots. When you write "citizen can only get one" you probably mean "one kind": the vaccines that you mention do in principle require 2 shots. And in most countries around the world, the two shots have to be of the same vaccine, which is another contraint. The remaining question is then if 65+ constraint applies to the first shot or the second?
This would lead us to a diagram that looks as follows:
Additional thoughts:
You could manage the shots by making the association Vaccination an association class.
There is an issue in the regarding the open/closed principle: if you'd add new vaccines, you might have to add different constraints on some. Alternatives:
Make Vaccine an abstract class (or an interface), with some more operations that need to be implemented by the concrete classes: getRequiredMinAge(), getRecommendedMinAge(), getRecommendedMaxAge(), getrequiredMaxAge(), instead of hard-coding the constraint.
Use a method Vaccine::checkCompatibility(c: Citizen) transfering the constraint verification to the Vaccine class
One could wonder if subclassing the vaccines is really required.
Related
I am making a class diagram. I have a Person class and an Address class. I am thinking there is a 'Has-A' relation between the Person class and Address class (Aggregation):
Am I right in marking the relationship as association?
Does it depend on us how we want the model the relationship?
For example, if I have two classes, Book and Library, I could say that Books shall not exist without a Library (composition) or I could say that Books may exist independent of library(Aggregation).
There is no one correct answer. There are many valid ways to model a scenario. In this case you could either mark the relationship between Person and Address as an association (more specifically aggregation), or you could mark it as a complex attribute.
Yes, details like that should be discussed with stakeholders / people who understand the domain you are modelling.
Is the association right?
Yes, you are right: a simple association expresses perfectly that a Person has an Address. Nobody could claim on the base of your narrative that your model would be wrong.
But modeling is a form of communication: You may well chose a different notation to add nuance in what you express, and you may decide for different semantics to tell how you see things in view of your needs.
Does it depend on us? Notation
In our example, you may want to clarify what you mean with the association by giving it a name:
Or you may prefer to clarify the role of the address in the association:
Or in complex diagrams you may prefer the shorter but equivalent property notation, nevertheless keeping in mind that "A useful convention for general modeling scenarios is that a Property whose type is a kind of Class is an Association end, while a property whose type is a kind of DataType is not":
Does it depend on us? Semantics
You could go for aggregation, but I'd strongly discourage it since UML does not define any semantic for it. So there's no benefit compared to a simple association.
You could consider composition. It might in general not be the best choice, as addresses exist independently of the persons. But in an application that creates separate Address objects for each Person, it could reveal how you intend to manage addresses.
Or you may want some richer semantics, for example with an association class to tell that people could have plenty of addresses of different kinds:
I have a class Tutor and there are some instances of that class can be course coordinators, can I represent the relationship using recursive association?
this is how I represented the association at first, which I think is not correct
Quick fix
In your diagram you claim that all Tutors are coordinating exactly a single Course. It's the consequence of 1 being the same as 1..1. But this is not what your narrative says:
some instances of that class can be course coordinators.
You should therefore replace the multiplicity on the Course side with 0..1. It which would translate some Tutors can be coordinating a Course (but not all).
Another alternative
The inconvenience is that the model does not define Course Coordinators. Maybe it's just the wording and doesn't matter. But may be there is more about Course Coordinator that would justify a separate class with additional properties and behaviors:
If it's a special kind of Tutor, just make it a specialization thereof, and let this additional class have the coordinating association.
If this is a special role that a Tutor but also other classes (Professor, Assitant, ...) could take, you'd better prefer composition over inheritance (object composition in OOP corresponds to UML associations). The association between Tutor and Course Coordinator would read "have the role of".
Not related:
A couple of additional questions for you (just to ensure that the multiplicities say what you meant):
One specific Course could be taught by several Tutors ?
No Tutor could teach more than one Course ?
A specific Course could have no Tutor for teaching (because * means 0..*)?
The same Course could be coordinated by several Tutors?
Currently I am trying to model a UML diagram for cars. I have the problem that besides the combustion engines also electric cars exist.
When you look at the diagram, you can see that the Golf has the data type Fuel for the attribute consumes, while the e-Golf has the data type EnergyType.
How would you adapt this diagram?
Inheritance is meant differently. You already define consumes an enumeration in the abstract class. Now in the inheriting ones you do not override this attribute but just assign fixed values. Plus you use a wrong notation in that case. It would be rather consumes: Energytype = electrical energy (etc.). This type anyway is superfluous since you would have it in the class type itself. A concrete electric car is of the type you want. So that enumeration would contain the possible concrete class types (if needed at all). Now you should rather concentrate on what the different car types are. The only common thing is probably the chassis which will be defined in the abstract car.
N.B. thinking this way of cars is what the dinosaurs actually do and which is why they have so much trouble. E-cars are much more different than classic cars. Basically you need to go back to the seats for humans inside for the abstract car.
Amendment
could be a way to express a car (there are lots and lots of ways to show variants and it takes weeks and months to get to something appropriate for cars). You see that the abstract car (written in italics) has no attributes but just associations with role names. Some to abstract classes and one to a concrete class (note that this is just something meant as example). The abstract classes just have associations and contain attributes which are agreed to be common to that thing.
Now if you're building some concrete car configuration you will only have concrete classes:
The MySuperNewCar has an electric drive with 4 wheels and 2 leather seats. I repeated the abstract classes in this diagram. But that's not needed (since you probably would already guess so).
So, thats one way to describe a car. There are much more ways which need long discussions. In any way you should get a consultant aboard who's talking UML fluently (in other words who's good at modeling things).
I would advise to use different names for attributes with different types. Instead of 'consumes' you could use 'energyType' and 'fuelType'.
So I'm currently self-teaching myself UML and I took an online quiz to help strengthen my understanding of it.
One of the questions asked:
How do you model the following situation with a UML2 class diagram:
"There are multiple different bird species, e.g. blackbird, thrush,
and starling."
And two available options were:
The diagram on the top is correct (and I understand why), however, the diagram on the bottom is incorrect. Why is this? Since the three birds inherit from the abstract class bird and conform to any abstract methods, aren't they all birds?
There's two possible answers to this I think:
The top is incorrect logically since you can't create an instance of a Bird on its own. Bird is an abstract classification of all bird species. You can only create Thrushes, Starlings and Blackbirds. I'm not sure what a Bird instance would look like, but it would be supernatural.
The bottom is incorrect syntactically because the abstract constraint should be applied after the class's name and type.
Personally I think I'd let the #2 one go (it's a mistake, who cares?) and focus on #1 which is, if I was in the business of birds, more important.
The UML 2.5 spec says on p. 98
The isAbstract property of Classifier, when true, 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.
So whether or not Bird is adorned with the keyword abstract results in the restriction of being able to not/instantiate it. If you need a Bird instance you leave it away. If you want to create an animal index you will probably have the abstract Bird which tells what you need to basically include in a bird's description. But you don't describe it by itself.
In your case, both diagrams are "correct" in general. It just depends on the context you did not explain properly. You can fulfill the requirement with both since there is no requirement that you may not instantiate Bird.
The requirement in the quiz says:
There are multiple different bird species, e.g. blackbird, thrush, and starling
But it does not says anything about what information you should hold about the bird species. So my first assumption is that the user would only be interested in the type.
The UML diagram:
is a valid solution for this requirement.
The two options in your quiz are also both valid solutions depending on how you look at the requirement. The requirement gave three examples which are all modelled explicitly in both solutions. "e.g." means there could be other birds and this fact is better described with the first solution. In the second solution you can have no instances of "Bird" that are not in the list of examples.
But this solution would only make sense if you could have some attributes and operations which are not shown - IMHO the minimum would be to keep track of the bird type - it is very awkward to retrieve this from the class name in most implementation environments.
Personally I do not think it is a good way to explain inheritance with such examples as in your quiz. Inheritance is costly in implementation (e.g. in most programming languages you end up with separate source code files per inherited class) and this cost should give you a certain benefit. This is mostly the case when the things to be depicted differ in theie attributes and behavior and you need different implementations. "Blackbird" and "Bluebird" might differ only in color (the color attribute is the discriminator). IMHO in this case it is better to have:
than
I'm modeling an app which will let users look for real estate properties. So it's going to be a website where users will be able to look for rentals and sales on houses, flats, castles, grounds, shops, parkings, offices. According to that, I'm hesitating in the class diagram. Should I generalize all the type of real estate properties, written above, from the class RealEstateProperty or should I just associate to it a class TypeOfRealEstate, knowing that the type "Ground" for example can be as well a real estate property as the ground of a property like a House or a Castle. Also a parking can be a real estate property as well as a parking of a House.
Anyone has an idea of what's the best way to do that ? Thanks in advance.
It depends of what features of different RealEstates your system has to implement. A class's features include attributes, methods and associations.
If all your potential RealEstates have same features, for example ID, type, price, date and responible agent, and you don't need to firther differenciate among them, than the associated type will do the work. Model RealEstateType as an Enum (or even class, if you expect to add new types) and associate it to a single RealEstate class.
If different RealEstates, on the another extreme, need to have different features, you will need to inherit those from the base abstract class. For example, Ground have an attribute "area", while building has "number of floors". Even methods can be different, or associations.
Following your example, you would like to link Ground to House. This is much cleaner in the second version - just an association between Ground and House class. In one-class version, you would have to link the RealEstate with itself and add spacial restrictopns (very "ugly" design).
In summary, try to think about the features of different RealEstates and make your RealEstate hierarchy based on their differences.
You can end up with a single class or several dozens of them. :) Try to keep this hierarchy as simple as possible (less classes), but enough to mark their different features clarly.