What's the difference between these types of association in an UML Class Diagram? - uml

I never understood the difference between these types of association. How should I interpret and in which scenarios should I use each one?

Given your diagrams all three cases are equivalent. So, I would go with the simplest version.
Adding a Purchase class allows to define features and behaviors of the link objects.
In the second case, Purchase is classifying the binary links between User objects and Product objects. That means each Purchase object is the link between exactly one User object and exactly one Product object. The outcome is the same as in the third case. Only there you have two link objects and one regular object, making the model a little more complicated. On the other hand, in this case you don't need to explain to your readers what an AssociationClass is.
In earlier versions of UML the two latter cases had a subtle difference. If the two ends of the AssociationClass are unique, each pair of User and Product can have at most one link. For a Purchase this is probably not what you want, because the user might buy the same product multiple times. But a stack overflow user can earn each badge only once. The AssociationClass would allow to model this.
Unfortunately this distinction has been thrown out. Therefore, AssociationClasses now don't have more expressive power than regular Classes, making them obsolete. I wrote a specification issue asking to put uniqueness back in.

So, according to my college teacher, the first and second one are equivalent. The second one would be "more correct" if the purchase had other atributes, since it doesn't you would opt for the first.
The third one differs a bit from the rest in the way that there can be multiple purchases where the User X bought the Product Y.
So, the first and second would be useful if we only want one record of a purchase between a User and a Product, and the third if we wanted to keep a purchase history for example

The first one is a named association. The name of the association (being purchase) is pretty pointless unless you are doing some exotic stuff. In this case User and Product have both some array referencing objects on the other side.
The second and third are just alternative notations for the same thing. That is you have an association class Purchase which in this case connects User and Product by adding some (not shown) functionality/attributes. Here the classes left/right do not see each other. It's only Purchase which makes the references.
Edit As noted by #JimL. the 2nd and 3rd differ in one respect: #2 has two* left and right where there should be a 1 to make it a match for #3. This would be the usual use for an association class. The * would make it different and probably very uncommon for the obvious application here.

Related

UML Class Diagram - Bidirectional Association

Scenario
A teacher at a university is able to search for a student by using their first name and last name. Similarly, a student can search for a teacher using their first name and last name.
What I've Done
I have used an association line with a label, searchesFor, to denote that a teacher can search for a student and vice versa. I have also used the no more than one multiplicity notation.
Question
If I don't use a filled arrow next to searchesFor to indicate the direction of the relationship, would my solution be naturally read as stated in the scenario?
No.
The UML specification does not provide any standard in such case. It is quite often that you don't show filled triangles, placing them only when the understanding might be unclear so the reader can think you just didn't notice ambiguity here.
You might use textual annotation (comment) to make it clear.
Also beware of the "database like" multiplicity usage. The multiplicity of one at each end means there's only object on each link end. If a teacher has searched a student, do you want to limit this students search to this single teacher only?
Finally search for is a very short lasting relation. Are you sure it is worth documenting like that at all?
I think your design is just wrong. There must be some instance to collect all teachers and all students from where you can get by name:
Sure you could simply relate students to teacher with a m-n relation. But that would result in a bad design. When you insert a new student, this must be added to all existing teachers (so they can find appropriately). Vice versa teacher/student applies the same way.
Whether or not you have a single Staff instance or separate ones for teachers and students depends.

Designing a class diagram for a domain model

First, don't think i'm trying to get the job done by someone else, but i'm trying to design a class diagram for a domain model and something I do is probably wrong because I'm stuck, so I just want to get hints about what i'm not doing correctly to continue...
For example, the user needs to search products by categories from a product list. Each category may have subcategories which may have subcategories, etc.
The first diagram I made was this (simplified):
The user also needs to get a tree list of categories which have at least one product.
For example, if this is all the categories tree:
Music instruments
Wind
String
Guitars
Violins
Percussion
Books
Comics
Fiction
Romance
I can't return a tree of Category which have at least one product because I would also get all subCategories, but not each sub category has a product associated to it.
I also can't remove items from the Category.subCategories collection to keep only items which have associated products because it would alter the Category entity, which may be shared elsewhere, this is not what I want.
I thought of doing a copy, but than I would get 2 different instances of the same entity in the same context, isn't it a bad thing ?
So I redesigned to this:
Now I don't get a collection of child categories I don't want with each Category, I only know about its parent category, which is ok.
However, this creates a tree of categories which is navigable only from the bottom to the top, it makes no sense for the client of ProductList who will always need a top -> bottom navigation of categories.
As a solution I think of the diagram below, but i'm not sure it is very good because it kinda dupplicates things, also the CategoryTreeItem does not seems very meaningful in the domain language.
What am I doing wrong ?
This is rather an algorithmic question than a model question. Your first approach is totally ok, unless you were silent about constraints. So you can assign a category or a sub-category to any product. If you assign a sub-category, this means as per this model, the product will also have the parent category. To make it clear I would attach a constraint that tells that a product needs to be assigned to the most finest know category grain. E.g. the guitar products would be assigned to the Guitar category. As more strange instrument like the Stick would get the Strings category (which not would mean its a guitar and a violin but just in the higher category.
Now when you will implement Category you might think of a method to return a collection of assignedInstruments() which for Guitar would return Fender, Alhambra, etc. You might augment this assignedInstruments(levelUp:BOOL) to get also those instruments of the category above.
Generally you must be clear about what the category assignment basically means. If you change the assignment the product will end up in another list.
It depends on the purpose of the diagram. Do you apply a certain software development method that defines the purpose of this diagram in a certain context and the intended readers audience?
Because you talk about a 'domain model', I guess your goal is to provide a kind of conceptual model, i.e. a model of the concepts needed to communicate the application's functionality to end users, testers etc. In that case, the first and the second diagram are both valid, but without the operations (FilterByCategory and GetCategories), because these are not relevant for that audience. The fact that the GUI only displays a subset of the full category tree is usually not expressed in a UML diagram, but in plain text.
On the other hand, if your intention is to provide a technical design for developers, then the third diagram is valid. The developers probably need a class to persist categories in the database ('Category') and a separate class to supply categories to the GUI ('CategoryTreeItem'). You are right that this distinction is not meaningful in the domain language, but in a technical design, it is common to have such additional classes. Please check with the developers if your model is compatible with the programming language and libraries/frameworks they use.
One final remark:
In the first diagram, you specified multiplicity=1 on the parent side. This would mean that every Category has a parent, which is obviously not true. The second diagram has the correct multiplicity: 0..1. The third diagram has an incorrect multiplicity=1 on the composition of CategoryTreeItem.
From my perspective your design is overly complex.
Crafting a domain model around querying needs is usually the wrong approach. Domain models are most useful to express domain behaviors. In other words, to process commands and protect invariants within the correct boundaries.
If your Product Aggregate Root (AR) references a Category AR by id and this relationship is stored in a relationnal DB then you can easily fulfill any of the mentionned querying use cases with a simple DB query. You'd start by gathering a flat representation of the tree which could then be used to construct an in-memory tree.
These queries could be exposed through a ProductQueryService that is part of the application layer, not the domain as those aren't used to enforce domain rules or invariants: I assumed they are used to fullfil reporting or UI display needs. It is there you could have a concept such as ProductCategoryTreeItemDTO for the in-memory representation.
You are also using the wrong terms according to DDD tactical patterns in your diagrams which is very misleading. An AR is an Entity, but an Entity is not necessarily an AR. The Entity term is mostly used to refer to a concept that is uniquely identified within the boundary of it's AR only, but not globally.

UML Relationships. Aggregation

I have a problem with my UML diagram and I'll be happy if you help me. I have relationships like
Object A (1)<>----(0..*) Object B
Object B (1)<>----(0..*) Object A
and I'd like to unite them. How can I do it? Thanks a lot.
Can you please define the term "unite them"? What exactly would you like to achive? An example could probably help.
Meanwhile, I can try to guess and give you two possible solutions. Maybe they help you to rephrase your question or even to find the solution:
In the Solution 1, I've just made a single relationship that describes both of yours. This can be used if there is only a single and clear criterion of the linkage between the objects. A typical n..m relationship. Objects A will each hold a collection of related objects B and vice versa.
For example a Person (A on the diagram) can join several Clubs (B) and a Club can have several members - there is only one logical relation behind this situation - membership.
Solution 2 is where there are actually 2 different ways to relate between those elements, each one 1..n. So, A holds a collection of Bs and B holds collection of As, but they are unrelated.
Extending the same example - a Person (A) can join only 1 Club (B) and a Club can have many members and hold their reference (col_a on the diagram). In the same time, a Club can have only 1 owner, and a Person can own several Clubs (col_b). Here we have two different logical relations - membership and ownership.
Of course, other multiplicities and navigabilities are possible, this is just an example to give you an idea.
Does one of these situations sound like yours?
UPDATE (after the 1st comment):
So, here is the updated solution 1:
This is an aggregation used here, and this is more a Group-member relationship. It suits perfectly the description of my first solution up there. Members (B) can be "shared" between the Groups (A) and Gruop does not have any special control over their lifetime.
The real Whole-part relationship would employ composition instead of aggregation (visually depicted with a black diamond, instead of a white one). Its semantics it that Whole object has a full control over the life of the contained objects (parts). In consequence, the Parts cannot be shared between several Wholes and must be destroyed if the Whole itself is destroyed.
Now you just need to find out which situation describes your problem the best, pick-up on of this solutions and eventually fine tune the multiplicities.
Here is a way you could represent this scenario in UML.
One server can contain 0 or many Functions (ie. aggregate relationship).
Each function must belong to one server. Or if it is a distributed function then it can belong to many servers.

Feedback on UML Class Diagram

I am creating a Class Diagram for a simple booking system for the theater. I would like to know if the diagram makes any sense and if anything needs to be changed (arrow directions) in order for it to be correct?
Thanks.
Image URL: http://i.stack.imgur.com/zWiGW.jpg
Here are some recommendations that you're free to incorporate or ignore as you see fit:
I don't agree with the relationship between Show and Venue. It seems more natural to have a Booking maintain the relationship between a Show and a Venue.
I don't see a Date for a Show anywhere. Did I miss it? That seems important.
Shows don't have Seats; a Venue has Seats.
A Ticket ought to entitle you to a Seat in a Venue on a particular date. I don't see that.
TicketType should be nothing but an enum.
Decompose User to have a Name, Address, and Credential classes. Separate the Credentials out from User.
A real payment system would need far more than what you have showing (e.g. CreditCard, etc.)
I think your model needs a lot of work.
In addition to what duffymo said, here are some generic observations not strictly related to this particular diagram but rather you modeling practices.
If an association is one way navigable then there is no need to name both ends. You have named both ends of all associations, but only navigable end needs a name.
Drop the 'can' from all association ends. In some cases there is a handy term, for example show can be hosted at a Venue. But in other cases it's perfectly fine and even common practice to name association ends same as the class at that end. (so name the Seat end simply Seats)
Avoid many to many relationships if you can. If you can't then look into adding an association class in between, it almost always makes sense.

Value object or entity

There is two things in my project Advertiser and BonusPrograms.
Business rules are -:
Advertisers will select bonus program from list of bonus programs.
Only one bonus program can be assigned at a time, previous bonus program will be discarded for that Advertiser.
BonusPrograms are not created by Advertiser, only assigned to them.
BonusPrograms are not created per advertiser, it is for all advertisers
Any new bonusprogram can be introduced at any time in project
My question are -:
1) I have created Bonus program as a separate agg root against Advertiser root aggregate because , advertiser does not create it, it only assigns it. Do I am correct ?
OR
2) Do i make BonusPrograms as valueobject under Advertiser Aggregate because only one bonusprogram is assigned to Advertiser, When a new one is assigned previous one is removed?
I'd go with option 3) which is that BonusProgram is an Entity, but not an Aggregate Root. It's hard to say w/o knowing more of your domain, but from what you described here, Advertising (or Marketing, or soemthing similar) is the aggregate, and Advertisers and Bonus Programs are entities under that aggregate. Not sure what the root would be for the aggregate from what you've said, but it doesn't sound like either Advertisers or Bonus Programs to me.
Firstly, let me say I agree with Paul, and you should accept his answer at some point. I'd have made this a comment but I can express my thoughts this way better.
You are asking two questions here, and there are two common sticky concepts in each.
The first question is the notion of where BonusProgram goes with respect to Advertiser if Advertiser is an aggregate root. This is definitely an interesting question, and depends on your domain and use cases. It doesn't depend on whether BP is a value object or entity though, as aggregates will typically contain both. The point of the aggregate is to simplify object traversal for external (to the aggregate root) objects. You accomplish that by picking one root entity that an external object can have a reference to, and only one (for a use case). This means that a client object can have a reference to Advertiser, but not BonusProgram. Advertiser will hold and necessary references to BP in order to satisfy the clinet object's request.
The second question is whether BP is a value object or an entity. Again the answer depends on your domain. The question to always ask yourself is whether you care about the objects identity or not. If you don't care, it is a value object; if you do care it is an entity. The classic case of a value object is Money - while you certainly care about it, you don't typically care about which dollar is which (one dollar is as wonderful as another)! In this case though, BonusProgram smells more like an entity, and you likely are interesting in knowing things like which BP was in effect last month and what were it's results compared to this month's BP.
Again, Paul is saying the same things and you should accept his answer.
HTH,
Berryl

Resources