OCL collection operation on list attribute - class

I'm modelling a problem in which there are students and courses.
Each courses have some other courses as prerequisites and I want to make an OCL constraint on the "joinCourse()" operation of students to allow them to join a courses if and only if they have finished required courses.
this is a draft of the UML class diagram I made:
now, my question is:
is possible to make a collection operation, like "includeAll" on a "list attribute" like finishedCourses?
I made this ocl constraint:
context Student::joinCourse(c: Course)
pre: self.finishedCourses->includesAll(c.requiredCourses)
correct?
thanks in advance!

In short: yes, it's correct.
Justification
In the UML 2.5 specifications there is a clear link between multiplicity and collection:
7.5.3.2. A MultiplicityElement is an Element that may be instantiated in some way to represent a collection of values. (...)
The OCL specification explains how self relates to the context (clause 7.3.4):
The OCL expression can be part of a Precondition or Postcondition,
corresponding to «precondition» and «postcondition» stereotypes of
Constraint associated with an Operation or other behavioral feature.
The contextual instance self then is an instance of the type that owns
the operation or method as a feature.
So in your expression, self refers to a Student, and a dot allows to access its properties, such as self.finishedCourse refers to a collection property.
OCL defines collection types (clause 11.6) and general operations that are well formed for all collections (clause 11.7.1):
includesAll(c2 : Collection(T)) : Boolean
Does self contain all the elements of c2 ?
post: result = c2->forAll(elem | self->includes(elem))
So self.finishedCourses->includesAll(c.requiredCourses) is a valid expression that is true or false exactly in the situation that you expect.
Additional remark
A property may represent an attribute of a classifier or a member end of an association. You could have represented finishedCourse as the end of a second association between Student and Course (being understood that all courses taken are not necessarily finished).

Related

mapping generalization constraints to sql (STI approcach)

I'm trying to model the following relationships between entities, mainly consisting of a partial, disjoint generalization.
original EERD
'mapped' to relational
Since I didn't need the subclasses to have any particular attributes I decided to use the "single table inheritance" approach, added the "type" field and moved the relationships towards the parent.
After that I had two choices to make:
1- type for the "business type" attribute
2- way to constraint participation to at most one of the 4 relationships based on the type attribute
For the sake of portability and extensibility I decided to implement no.1 as a lookup table (rather than enum or a hardcoded check).
About no.2 I figured the best way to enforce participation and exclusivity constraints on the four relationships would be a trigger.
The problem is that now I'm not really sure how to write a trigger function; for instance it would have to reference values inserted into business type, so I'd have to make sure those can't be changed or deleted in the future.
I feel like I'm doing something wrong so I wanted to ask for feedback before going further; is this a suitable approach in your opinion?
I found an interesting article describing a possible solution: it feels a bit like an 'hack' but it should be working
(it's intended for SQL Server, but it can be easily applied in postgres too).
EDIT:
It consists in adding a type field to the parent table, and then have every child table reference said field along with the parent's id by using a foreign key constraint (a UNIQUE constraint on this pair of fields has to be added beforehand, since FKs must be unique).
Now in order to force the type field to match the table it belongs to, one adds a check constraint/always generated value ensuring that the type column always has the same value
(eg: CHECK(Business_type_id = 1) in the Husbandry table, where 1 represents 'husbandry' in the type lookup table).
The only issue is that it requires a whole column in every subclass, each containing the same generated value repeated over and over (waste of space?), and it may fall apart as soon as the IDs in the lookup table are modified

How to implement disjoint (nonoverlapping) subtype with total completeness in MongoDB?

I designed an entity relationship diagram (ERD) with the goal of creating two child entities (INSTITUTION and SPACECRAFT) of a parent entity (LOCATION), which is distinguished depending on the value of a boolean attribute (IS_SPACECRAFT). Implementing this in MongoDB, I'd like to link the INSTITUTION entity to another separate entity when IS_SPACECRAFT is false (0), and the SPACECRAFT entity to this other separate entity when IS_SPACECRAFT is true (1).
Right now, I am doing this manually by creating two attributes (SPACECRAFT_ID and INSTITUTION_ID) in this unrelated entity and pasting the object ID of either the INSTITUTION or SPACECRAFT entity in this attribute depending on the value of IS_SPACRECRAFT. But this inevitably leads to one of those attributes being NULL, which I think is poor database design and is something I'd like to avoid. With that in mind, is there a way to link another entity (i.e., as a foreign key) depending on a Boolean value in MongoDB?
Attached below is the ERD I mentioned earlier so the hierarchy is clear. The discriminator (d) is meant to represent a disjoint (overlapping) subtype, and the double lines represent a total completeness constraint, such that all the member of the parent LOCATION entity are in either SPACECRAFT or LOCATION, but not both.
For reference, a disjoint subtype is defined as:
Disjoint subtypes, also known as nonoverlapping subtypes, are subtypes that contain a unique subset of the supertype entity set; in other words, each entity instance of the supertype can appear in only one of the subtypes.
And total completeness is defined as:
The completeness constraint specifies whether each entity supertype occurrence must also be a member of at least one subtype. The completeness constraint can be partial or total. Partial completeness means that not every supertype occurrence is a member of a sub-type; some supertype occurrences may not be members of any subtype. Total completeness means that every supertype occurrence must be a member of at least one subtype.
https://www.google.com/books/edition/Database_Systems_Design_Implementation_M/4JN4CgAAQBAJ

Does a birthdate/deathdate class should be a composition or an aggregation to an individual class?

The entity is a person.
So the entity have a birthdate and maybe already have a deathdate.
But this dates can or cannot be informed (depends of the entity and avaibility of the informations) ; so the entity might have none of those.
But I feel to do mess with the cardinality and the relation type.
How should I represent that ?
I have created an abstract class Individual. It leads to 2 final class : Person (identified person) or Pseudonym (anonym person).
It linked to a class Birthdate and a class Deathdate (both are generalized as a class Date).
[Birthdate]----<>[Individual] relationship is :
one (optional)-to-many (0..1 - 1..*)
0..1 : Because birthdate can be omitted and individual can have just one date of birth.
1..* : Because birthdate must concern at least one, but can concern severals individual.
[Deathdate]----<>[Individual] relationship is :
one (optional)-to-many (0..1 - 1..*)
0..1 : Because the individual isn't dead yet and can die just once.
1..* : Because deathdate must concern at least one but can concern severals individual.
But since, theoretically, everyone have a birthdate (and will have a deathdate) I was tempted by a composition. But some might prefer keep these dates secret and I wondered if composition could allow that.
Futhermore one date can correspond to severals individuals and here also I guess composition isn't possible then OR else it's me who did the confusion between Individual class and its instances (the individuals) and then Composition would be possible but not with the aforementionned cardinality.
At the moment I chose that :
Aggregation :
___________ _______________
|Birthdate|0..1-----1..*< >| |
___________ | <<Individual>>|
|Deathdate|0..1-----1..*< >|_______________|
But I hesitate with this one
Composition :
___________ _______________
|Birthdate|0..1-----1<#>| |
___________ | <<Individual>>|
|Deathdate|0..1-----1<#>|_______________|
What is the right answer ? Thanks for the attention.
There is a number of issues with the approach.
First - using a class for dates is simply an overkill. Both birthdate and deathdate are attributes of a specific person and can be easily modelled as inline properties of the Individual class. Unless there is some significant reason to use something more than the good old Date DataType, keep with the standard approach.
For visibility issue, as object oriented principles say you should not expose the properties directly anyway. Rather than that you should have an operation responsible for retrieving birthdate and deathdate that will control if the date can be read or not. You may add boolean attributes that will support that, but it isn't necessary if the ability to see the dates depend on some state of the Individual or other things (e.g. "who" asks). In the former case you may also wish to still show explicitly those boolean attributes as derived ones.
If you insist on using a class for dates (e.g. as you want to have a Wikipedia-style "Born on date"/"Deceased on date" collections) you should create just one class Date and build associations to this class pretty much similar to the way you did in your second approach. In such situation, the multiplicity does not work "database style" but is a property of association itself. In particular association you have one birthdate/deathdate and one Individual. By default you will have two 1-0..1 association one for each but depending on the approach you may have much more complex approach as well.
I'll later add diagrams for more clarity.
One last remark.
Do not use << >> for the class name. Those are reserved to indicate stereotypes.
If you want to indicate that Individual is abstract either show it in italics or (if your tool doesn't allow that) use <<abstract>> stereotype.

UML Class Diagram: Attribute or Association?

Now i have two classes, named patient and doctor:
Patient() {
public:
//functions here
private:
Doctor doctor;
Date dateAdmitted;
Date dateDischarged;
}
Doctor() {
public:
//functions here
private:
//data members here
}
In my UML class Diagram for patient class, do i need to include the doctor and date as attribute? or i just represent them by linking them as association?
If attribute it should be like:
Patient
doctor : Doctor
dateAdmitted : Date
dateDischarged : Date
According to UML syntactical rules, both solutions are valid - both class attributes and associated classes are so called class properties and can be shown as attributes (inside the class) or as separate classes, linked via association. For both these class features you can define name, multiplicity, scope, etc. Please refer to UML spec for detailed technical information.
However, the common practice if the following:
if the property is basic data type (int, boolean, date, etc) -> show
it inside a class, as attribute
if the property is full fledged
class -> show it as a separate class entity and use association to
display their relationship
This practice make sense, as "int", "boolean" or "date" do not have their own custom properties and it is enough to show them inside a class (withoult losing information about them). Classes, on the other side, have their own features (attributes, methods and own associations, generalizations, etc) and therefore "deserve" more space on the diagram.
Concluding with the direct answer to your question: show Doctor as a separate class on the diagram, connected with Patient via association (note the property name displayed as associationEnd name). Keep both dates inside the Patient class:
The following diagram is equivalent and valid, but you might agree that the first one is visually clearer (imagine some atts, methods and relationships or the Doctor class) and therefore recommended:
UPDATE (after the comments)
Note: Composition is used for Dates, to reflect a strong relationship of the Whole-Part kind and the fact that these Dates cannot be unlinked from their context.
The other association (Patient-Doctor) is a common assotiation and the corresponding link can be broken anytime (for example to change a Patient's Doctor).
In UML, you would model relationships between classes as an association. Attributes should be for data types.
That they will most likely end up as fields in e.g. Java does not play a role at this stage yet.

Should I null or add new "not selected" values?

I have an MVVM application, EF code first.
In my model I have an Appointment entity and this entity has navigation properties which are Types such as AppointmentType; AppointmentDuration; AppointmentConsultant. These were all specified as 1-1 in initial requirements. So my Appointment model has the [Required] annotation on the Ids' of these types.
Of course 6 months after the client starting to use the system in anger they have identified that if they mark an appointment as "DidNotAttend" then they don't want to have to select the, once mandatory, types.
My question is, seeing as these types all exist in database tables, and my code has enumerations matching the Ids, would you add a new types, and enum values, for each of these with description of NotSelected, or simply amend the underlying database structure and model to make these not required/nullable integers, and write business logic in view model to say, "if AttendanceIndicator is NOT 'DidNotAttend' then check each is NOT 'NotSelected'"?