We often encounter class models, in UML modeling, that state a 1 x 1 or 1 x 1..* or 1..* x 1 or 1..* x 1..* association between given classes.
Take the example: Player 1..11 x 1 Team.
Wouldn't that impose a practical problem, in which it wouldn't be possible to determine what comes first: the team or a player?
In the example, a team would need a player, at least, to exist, while a player, to exist, needs the team.
Am I misinterpreting something?
Trying to implement it, you wouldn't be able to instantiate a Team, because you'd need at least one Player, and if you try to instantiate the Player, the Team would be missing.
How are 1 x 1 associations possible?
Thank you for your time!
When a model as a 1..11 relationship (Team - Player) there is no "what comes first". There need to be 11 Players and these can be connected to one Team. Only when the connections are all made you have a complying model. You can point out that players form a team by adding a composition. But usually from a programming aspect this does not add much semantics. You need to have the instances anyway in order to create the connections. So the Team will likely have an array of 11 Players and in order to work, none of them must be Null.
The same goes for 1..1 relations (plug/socket). Only when they are connected you have a complying model. From a modeling perspective a 1..1 is often used if you need a rucksack for one of the two classes. Then you bind another one with separate information. This can then be used together with other classes which are only interested in this contents and not the carrier itself.
You are correct. You must satisfy all the constraints somehow. Either create everything at once or relax your constraints. For example, a team can still exist as a team without any players, but a team must exist for a player to join it.
Your question "How are 1 x 1 associations possible?" refers to the issue of mandatory mutually inverse references, or, in DBMS jargon, cyclic foreign keys, which may indeed create an object/row creation or update problem in a data management app or its underlying database (DB).
There are two approaches how to deal with it: 1) Relax the mandatory reference constraint in at least one direction, 2) Allow intermediate app/DB states that do not have to satisfy the constraint.
1) While we know that in reality a team always includes more than zero players, we may choose not to implement this constraint for pragmatic reasons, such that we can more easily create a team data object (or DB row) without immediately assigning player objects/rows to it.
2) In our app, we may allow an intermediate state where a team has been created without any players assigned to it, and correspondingly in the underlying DB, we may instruct the transaction manager that the foreign key constraint is only checked when the entire transaction (consisting of first creating an empty team, then creating 11 players, such that each of them is assigned to the team and the team is assigned to them as their team) is completed. This can be achieved with the SQL clause DEFERRABLE INITIALLY DEFERRED, see the section Cyclic Foreign Keys of the post "Deferrable SQL Constraints in Depth".
It depends what kind of model it is. A UML model might be a model of the real world, e.g. a human hand has 1:1 relationship with a human arm. This 1:1-association models a biological fact (ignoring disabilities).
A UML model might also be a model of the functionality of an application. If the application enforces that every team has 11 players and every player has one team (e.g. they are all created at once by filling out a form with a "Save"-button), then the 1:11-association correctly models the functionality of the application.
A UML model might also be a technical model of classes in some programming language or tables in a database. In that case, the 1:1-associations are only possible if your programming language or database system allows creating the instances on both sides simultaneously, or at least in the same transaction.
Side note: When modeling teams and players, you might consider an association between Team and Person, with multiplicity 0..* and role name 'player' on the Team side.
Related
We need to create a booking system that allows rape victims to book sessions with a counsellor (who is a volunteer therefore is not on duty 24/7) online. The organisation used to do the booking process over the phone, writing down important information.
This is the package diagram I created for a project. I am not sure: am I allowed to just use the packages as entities for the class diagram?
A package is a tool to structure models by grouping somehow related pieces into namespaces.
It is not unusual to recognize a decomposition that coincides somehow with larger components (e.g. Client, Application and Data). But it is not correct to use packages as a substitute for a class. It may even look confusing.
It is not a problem to keep enclosing or nested packages such as Booking system in a class diagram. But you should use a proper class box for classes. You would then be able to show not only the properties but also the operations in a different compartment. Last but not least, you could be more precise in the relationships between classes, considering that packages are only related via dependencies and some special package operations, whereas classes can be related also with associations, inheritance, etc..
For example, your diagram tells only that Booking is dependent on Client. And this means the content of one package needs to know about the other packages. But in reality Client and Booking should be associated i.e. an instance of Client would be related for a longer time to some specific instances of Booking. In this case, you'd expect that you could easily navigate from the one to the other. Associations also allow to specify multiplicity, e.g. that one client could have 1 or more bookings, but each booking would be for only one client.
Other remarks, unrelated to the question:
Your comment box suggests that you try to explain the purpose of the system, perhaps for some stakeholders. You may therefore consider using a use-case diagram to show the big picture with the different actors and the goals they want to achieve with the system.
In a class box, you could add an «Entity» stereotype above the name of the class. Entities are domain classes that matter to the users.
Data storage system seems not to fit in the diagram: it's not really an entity. Perhaps it's a class, a component or a package, but not really an entity.
I work in cattle production and I am learning about database design with postgreSQL. Now I am working on an entity attribute relationship model for a database that allows to register the allocation of the pastures in which cattle graze. In the logic of this business an animal can be assigned to several grazing groups during its life. Each grazing group in turn has a duration and is composed of several pastures in which the animals graze according to a rotation calendar. In this way, at a specific time, animals graze in a pasture that is part of a grazing group.
I have a situation in which many grazing groups can be assigned to many animals as well as many pastures. Trying to model this problem I find a fan trap because there are two one-to-many relationships for a single table. According to this, I would like to ask you about how one can deal with this type of relationship in which one entity relates to two others in the form of many-to-many relationships.
I put a diagram on the problem.
model diagram
Thanks
Traditionally, using a link table (the ones you call assignment) between two tables has been the right way to do many-to-many relationships. Other choices include having an ARRAY of animal ids in grazing group, using JSONB fields etc. Those might prove to be problematic later, so I'd recommend going the old way.
If you want to keep track of history, you can add an active boolean field (to the link table probably) to indicate which assignment is current or have a start date and end date for each assignment. This also makes it possible to plan future assignments. To make things easier, make VIEWs showing only current assignment and further VIEWs to show JOINed tables.
Since there's no clear question in your post, I'd just say you are going the right way.
I was reading about owned entity types here https://learn.microsoft.com/en-us/ef/core/modeling/owned-entities#feedback and I was wondering when I would use that. Especially when using .ToTable(); although I am not sure if ToTable creates a relationship with keys.
I read the entire article so I understand that it essentially forces you to access the data via nav properties and prevents the owned table from being treated as an entity. They also say Include() is not needed and the data comes down with every query for the parent table so its not like you are reducing the amount of data that comes back.
So whats the point exactly? Also whats the point of "table splitting"?
It takes the place of Complex types with the option to set it up like a 1-1 relationship /w ToTable while automatically eager-loaded. This would use the same PK in both tables, same as 1-1.
The point Table-splitting would be that you want an object model that is normalized, where the table structure is not. This would fit scenarios where you have an existing table structure and want to split off related pieces of that data into sub-entities associated with the main entity. With the ToTable option, it would be similar to a 1-1 relationship, but automatically eager-loaded. However when considering the reasons to use a 1-1 relationship I would consider this option a bad choice.
The common reasons for using it in normal 1-1 relationships would include:
Splitting off expensive to load, rarely used data. (images, binary, memo)
Encapsulating data particular to a single application off of a common entity. i.e. if I have a "Customer" which is used by a billing system vs. a CRM I might have "CustomerBillingData" and "CustomerCRMData" owned by "Customer" rather than an inherited BillingCustomer / CRMCustomer. As there is a "single" customer that may serve one or both systems. Billing doesn't care about CRM data, CRM doesn't care about Billing. If all data is in "Customer" then both systems potentially need to be updated, and I cannot rely on constraints when the data is optional to the other system. By using composition I can enforce required data for a particular system.
In neither of these cases would I want to use table-splitting or anything that automatically eager-loads, so Owned Types /w ToTable would not replace 1-1 relationships by any stretch. It's essentially a more strict version of complex types, I'd say it's strictly used for entity organization. Not something I'd admit to wanting to use very often.
I'm done DDD for a couple of years now and still its challenging when it comes to designing Aggregates. Thats the fun part of DDD and it makes your head spin. I'm asking this question since I'm architect in a project and we're in the middle of designing the model. Its an iteration when model evolves parallel with GUI and requirement gathering together with customer.
Now to the problem. Our scenario is that we are facing some Aggregates that are growing into very large AR's. I think I'm good at finding Value objects and avoiding the anemic domain model trap. But I've never been in this situation.
One example is that our system should represent a mobile telecom antenna. The antenna is located on a green field. But the antenna can have a shelter with equipment. Antenna can have microwave links, it can have fiber lines in ground, it can have radio elements, it can have power supply. Face it. If Antenna is terminated... all these dependencies are removed as well. Since they are part of the installation (except for the green field :))
But You get the picture. The antenna model is complex... And large AR's are inflexible regarding to concurrency locks, performance, memory consumption.
After reading Vaughn Vernons very good paper on Effective AR design http://dddcommunity.org/library/vernon_2011/ I realize that We need to start chopping our big AR's up in pieces.
My Idea is to do like Vernon suggest to move out for example MicrowaveLinks to a separate AR (even if its not in reality).
The MicrowaveLink Entity, now AR, is reference Antenna by Id. In MicrowaveLink Entity class we have a value object property that is AntennaId.
Our Uses cases support this scenario. We rarely list antenna and links together. So loading MicrowaveLinks is possible through a MicrowaveLinkRepository.ListByAntenna(Guid antennaId)
1) Have you done this AR split before and how did you do it?
2) Did you manage to support this AR --> AR relationship intact through both domain constraints and DB (we use EF 5 as ORM)?
My optimal goal is to be able to skip a Antenna.Microwaves Collection on Antenna. So Antenna are not aware if Links. The Links are aware of what Antenna they are mounted on.
And At MicrowaveLink Entity I only want a AntennaId Property, with hopefully, a DB Constraints that make sure that Antenna exists.
I'm aware of that I can manually add FK constraints in Seed method in EF or in DB directly through T-SQL scripting. But can this relationship be supported in some way by EF5 Code First Fluent mapping?
By the sounds of it you have an Installation AR. When requiring an AR in another you should model the contained AR as a only the ID in the container or a VO if required.
You need to have hard edges around your ARs.
Back to the Order / OrderLine example :)
An OrderLine seems to 'require' a Product but you shouldn't ever give a Product instance tot eh OrderLine. Instead only model, say, the ProductName and ProductId as a VO in the OrderLine. Now you have a distinct edge to your Order AR.
Hope that helps somewhat.
In Core Data, most of the time relationships are modeled bidirectional. But the docs say in another place:
It typically only makes sense to model
a to-one relationship in one
direction.
Within Core Data you should always use a bi-directional relationship unless you have an extreme edge case. If you use one directional relationships then you are going to incur performance penalties within core data itself as well as have issues with referential integrity.
Unless you know specifically why you need a uni-directional relationship then you should always do a bi-directional relationship; the rule is that simple.
While Franci's answer is interesting, I have to disagree with it. Even in the examples he provided you should have a bi-directional relationship. There are almost no situations where a uni-directional relationship is going to be a better fit.
The answer is determined by the referential integrity requirements you want to enforce. If updating or removing the object on either side affects the object on the other side of the relationship, you need two-way. However, if updating/removing the object on one side does not affect the object on the other, then a one way is a better model.
Take for example a parent-children model with a 0..n : 1 cardinality (I prefer the 1 : 0..n representation, but for the sake of argument let's reverse it). Adding a new child, updating an existing child or deleting a child has no effect on the parent object, so there's no need for the parent to know explicitly about all the children (except when it comes time to pay college tuition). However, removing the parent has an adverse effect on the children objects, as they need to be deleted or re-parented, otherwise are orphaned and in an invalid state. Thus, it's better to model it as a one-way relationship. Another example is inventory - parts catalog relationship, again with 0..n : 1 cardinality.
It's a matter of ownership: usually it doesn't make sense to have a bidirectional relationship because an entity conceptually owns the other one.
Think about some examples. If you have a structure in which you have users and an user can have a simple bank account associated with him. If you make the relation bidirectional you mean that an user owns an account but also an account owns an user.
This will make sense because you don't want to delete an user whenever you delete his account. That's why usually you don't need to have it bidirectional: because it's an additional constraint that is not needed since most of the time you will have an entity that has the other but not vice-versa.
I think you read the whole document about relations you referenced in your question.
The document also describes all disadvantages of using unidirectional relations, and that only under very rare circumstances it makes sense to create unidirectional relations.
As a general rule i would strongly recommend creating bidirectional relations, except you are knowing exactly why not to do so.