How to Model data using UML for this situation? [closed] - class

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
The Situtation is that there is a data named Progress which has 2 valid values (suppose 'A' and B). this means Progress = 'A' or Progress = B. A is just a string, but B is not string. B itself has some valid values (suppose strings: 'V1', 'V2', 'V3'). progress can be A which is a string or can be B which is 'V1', 'V2' or 'V3'. How to model this data?
If B is just a simple string (just like A) so we can define Progress as a string but i think one solution is defining progress as a class which has two children: Class A & Class B. Class B has 2 fields: Id & state so we have 3 IDs which correspond to 3 states: 'V1', 'V2' and 'V3' and Class A with a const field called state with fixed value 'A'. so with this solution progress can be objects A or B which has a state.
Please help me if such design is not good or if there is any design pattern for such situation.

First of all, since I'm not 100% sure if you speak about classes in a typed language or objects in a dynamically typed language, I'd like to clarify the obvious: UML uses typed objects. So object instances such as progress must be of a class Progress that defines their properties and behaviors.
If your question would really be only about data and values, since there is no overlap between 'A' and 'Vn', the easiest way would be to define Progress as a class with a sole property that is of type String.
But from your narrative, I understand that it's not just about data but also about semantics and potentially object behaviors:
One way to address your requirement is to use class specialisation: Progress would have a generalization set with two specializations, ProgressString (with a sole String property) and B (with itself having a string property). Moreover the generalization set would have the constraint {complete, disjoint}
Another way is to use object composition (caution do not confuse object composition with UML composition): Progress would have two properties, a String and a B (defined as above). If you'd give them a multiplicity of 0..1 you could use a constraint to make sure that it's either the one or the other but not the two.
In both cases, if you want the string to be limited to the possible values that you have documented, you'd need to add a constraint. Alternatively, you could go for a more expressive model, using an «enumeration» to make explicit the possible values (as qwerty_so suggested in the comments).

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

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.

Is there a way of allowing an end-user to modify enumeration values once application is released?

I am just starting out with CodeFluent and beginning to really like it. My question is: I set a property of an entity to enumeration. How can I allow an end-user to add extra values (that are stored afterwards as additional choices) to an enumeration? Or should I use another entity to store those values/choices instead?
For instance: let's say I have a product and a producttype. My producttype is an enumeration (frozen, fresh, seasonal), and down the road, the user wants additional types (i.e.: organic, stationary). Should those be enumeration values or a separate entity?
If a separate entity.....I'm not really sure how I define the relationship (1 to 1, 1 to many - i.e. 1 producttype can have many products)?
You can't add values to an enum at runtime, that's impossible in .NET, so it's also impossible with CodeFluent.
So, you want to create another entity that will store the list of enums. That would be a 1:M relation. This is how you would layout that relation:
Each enumeration value would be a row in the ProductType table. With CodeFluent, you can declare "instances" for an entity that will become rows in the final table, so here, you can declare your initial enum values using instance, so use the instance grid on the ProductType entity, and add instances:
Note in this case, maybe you want to create the ProductType's Id property as an int without identity (if you don't want those enum int values generated by the database).

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'"?

Entity framework 4 model first using money value object

I want to use a Money value object in my application. I have found several examples of a Money datatype. But I can't figure out how to use them with EF4. I would like to store each amount as a Decimal/CurrencyCode pair (where currencycode is a string - "USD", "SEK", etc) in the database. I tried creating a complexType but I couldn't get that to work. Is this possible?
It should be definitely possible. Your complex type is just pair of decimal and string property. It is exactly what complex type are used for. Depending on your approach you must do:
Database first:
You will define your database first. Your table will contain money and varchar columns representing your new type. When you update your EDMX model from database it will include it as scalar properties to your entity. You must remove those properties. Then go to model browser and create new complex type. Return back to entity and add complex property of your new complex type. And at the end you must go to entity mapping and map your complex type to those database columns.
Here is basic tutorial from MSDN but from unknown reason they didn't include such elementary details like screenshots. Here is some video from channel9.
Model first:
This is similar to database first but you don't have to deal with database creation and mapping. It will be generated for you.
Code first (EF 4.1):
You must create separate class for your complex type and use it as property in your entity. You should not need to map it by default - mapping should be infered. If it doesn't work you can map complext type either by using ComplextTypeAttribute annotation or by defining mapping in DbModelBuilder.
I can further extend approach you need to use if you provide more details.