I've been working on putting together a rough conceptual model of an E-commerce website that basically allows users to resell concert tickets. It's purely conceptual and not something i'm actually making!
Anyway I've put together a domain model and I was hoping for some feedback. I've made class model before and modelled databases but found it quite difficult differentiating between them.
I've seen the words rich and anaemic thrown around a lot and I believe my model is anaemic. Would simply notating more behaviour make it rich?
Are my relationships correct? Have I correctly used my aggregations and compositions?
I would love any suggestions on improvements.
Thanks in advance.
You have the right idea, but some of the UML is incorrect and a (business) domain model shouldn't have a User.
Some examples of problems I see:
A User is probably not a Bidder and a Seller; rather, a User can play a Role of Bidder or Seller.
Generalizations do not have multiplicities.
It makes no sense to me for a Ticket to HAVE an Artist. A Ticket generally allows a Person to be admitted into a Show, and an Artist performs at a Show.
Compositions can have at most one composing class.
I would remove compositions and aggregations from a conceptual model. Otherwise, I don't think it's anemic as a conceptual model. The next step would be to add behavior to it as an OOA model and generate some code from it. Please see Leon Starr's How to Build Articulate UML Models article for more help.
As Jim says, you're not entirely clear on how composition and aggregation work. This example might be helpful. Tom Pender (author of "The UML Bible") uses it in his classes.
Suppose you have a car factory and you make cars. A car has an engine. In order to be a car, it has to have one; if you haven't put it in it isn't a car yet. But also, the engine is part of a car. The only reason to have the engine is to put it in the car. So, the engine has no identity or lifetime independently of the car. That's composition.
Now, suppose you have a junkyard. Same car, many years later. You can sell any items off the car and it will still be that car. If you sell the engine, the car will be the car without an engine. That's aggregation.
So, in a manufacturing context, a car is a composition of parts, and in a junkyard context, a car is an aggregation of parts. The point is that in composition, the lifetime of the parts is tied to the lifetime of the car, and in aggregation, it isn't.
Looking at your Ticket object, I would say that Venue and Artist are in a composition association with it. While the Venue and Artist certainly are not dependent on the ticket for their existence, you have to keep in mind the context. You're doing e-commerce. Your artist and your venue interact with the e-commerce system via tickets, and not in any other way. So composition. On the other hand, tickets are most certainly NOT composed of Orders. If that were so, there would be no such thing as an unordered ticket! So, tickets and orders have a simple association, not aggregation or composition.
As for your bidder and seller, they are users. So you have your inheritance arrows backwards. If Bidder and Seller have specialized user behavior that is independent of one another (e. g. "OfferBid" and "AcceptBid"), then they need to be modeled as specializations of the User class. If they do not, then they are just two users that are acting in different roles, and can be modeled as such.
Related
I have short question about class diagrams. In my book we have class Person and class Gender and agregation arrow between them(with diamond pointing to person). Now, in general when I want to decide whether we have agregation or not I am using one of these two rules:
1.When you destroy class that is whole, than part can exist without it;
2.Class that is part in agregation relation, can be mutual to one or more wholes.
Now if we look at this example and rule number 2, it is OK, because one gender is mutual to one or more persons. But for the first one, if there is not person, than we can't talk about gender right?So I would set composition here. Probably I am missing main difference between these two. Any help is appriciated.
In general
Your rule about when using aggregation is not wrong. But it's unnecessarily complex. There is a simpler much simpler rule about when you'd better use aggregation: never.
This may sound provocative, but the hard truth is that the meaning of aggregation is not defined in the UML specifications, which makes it ambiguous and subject to a lot of unnecessary time-consuming debates:
Sometimes a Property is used to model circumstances in which one instance is used to group together a set of instances; this is called aggregation. (...) Precise semantics of shared aggregation varies by application area and modeler.- UML specifications 2.5.1, page 112.
I know, it comes as a shock. For years in my career, I have myself selected very carefully aggregation whenever there was a part-whole relation with non-exclusive ownership. But when I came accross James Rumbaugh famous quote, I challenged my own assumptions and realized how vain and subjective this quest was:
Keep in mind that aggregation is association. Aggregation conveys the thought that the aggregate is inherently the sum of its parts. In fact, the only real semantics that it adds to association is the constraint that chains of aggregate links may not form cycle (...) In spite of the few semantics attached to aggregation, everybody thinks it is necessary (for different reasons). Think of it as a modeling placebo.- James Rumbaugh in Unified Modeling Language Reference Manual, chapter 14.
So, whenever you have aggregation in a model, you could simply replace it with an association without real loss of information.
In your specific example
The association: Person ----- Gender expresses perfectly that a person has a gender, and that several persons can share the same gender.
If you want to be super-accurate, you could use the dot notation (with a small dot on Gender side). This would convey the information that Person owns the end of the association.
Composition would definitely be wrong here, because it's an exclusive ownership and no two persons could share the same gender.
Aggregation is ambigous: what is the whole, what is the part? If gender is a part, wouldn't character be a part as well. And what with the name, then ?
A final remark: if you want to implement this with Person having a gender:Gender property (an OOP mechanism called "object composition") the, you don't need aggregation (even if it's a popular practice).
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.
I'm implementing a college system, and I'm trying to use DDD. I'm also reading the blue book. The basics entities of the system are Institution, Courses, Professors and Students. This system will allow a lot of Institutions, each having its courses, students and professors.
Reading about aggregates, all entities fits inside the aggregate Institution, because doesn't exists courses without Institution, the same for students and professors. Am I right thinking in that way?
In some place the professors will access the courses that they teach. Using this approach, should I always access the courses through Institution? This implementation seems strange to me, so I ask myself if Professor, as Students should be their own AR and have their Repository.
Even though you have accepted an answer I am adding this anyway since a comment is too short.
This whole aggregate root business trips up just about everyone when starting out with DDD. I know, since I have been there myself :)
As mentioned, a domain expert may be helpful in some cases but keep in mind that ownership does not imply containment. An Order typically belongs to a Customer but the Customer is not the AR for an Order since an Order can exist without a Customer. You may think: "But wait, that isn't really true!". This is where is comes down to rules. When I walk into a clothing store I can purchase a pair of shoes. I am a customer but they have no record of me other than a receipt I can produce. I am a cash customer. Perhaps my particular brand of shoe is not in stock but I can still order it. They will contact me once it arrives and that will probably be that and I'll in all likelihood still not be registered in any computer system. However, that same store is registered as a Customer with their supplier.
So why this long-winded story? Well, if it is possible to have an Entity stand alone with only a Value Object representing the owner then it is probably going to be an AR. I can include some basic customer information in a CustomerDetails value object in an Order? So the Order can be an AR.
No let's take a look at an OrderLine. Can I include some basic OrderDetails information on an OrderLine? This feels odd since a number of order lines constitute an Order. So it isn't quite as natural.
In the same way a GrapeBunch has to have a GrapeStem and a collection of GrapeBerry objects.
This seems to imply that if anything can be regarded as optional it may indicate that the related instance is an AR. If, however, a related instance is required then it is part of the AR.
These ideas are very broad but may serve as guidelines to consider your structure.
One more thing to remember is that an AR should not be instanced in another AR. Rather use the Id or a Value Object representing the relationship.
I think you're missing some transactional analysis - what typically changes together as part of the same business transaction, and how frequently ? One big aggregate is not necessarily a problem if only 2 users collaborate on it with only a few changes per day, but with dozens of concurrent modifications it could become a contention point.
Besides the data inventory and data structuration aspect of the problem, you want to have an idea of how the system will be used to make educated aggregate design decisions.
Something that might help you to separate those entities into different aggregate roots is to ask you: Which one of those must be used together? This is usually helpful as a first coarse filter.
So, for example, to add a student to a course, you don't need the Institution?
In your example about a professor accessing the courses he teaches. Can he access them by providing his professor id rather than the professor entity? I he provides the professor id, then the entities won't be associated by a reference but by an id.
Lots of this concepts have evolved a lot since the blue book was written 12 years ago. Even though the blue book is a really good book, I suggest you to also read the red book (Implementing Domain-Driven Design by Vaughn Vernon). This book has a more practical approach to DDD and shows more modern approaches, such as CQRS and Event Sourcing.
A professor and a student can exist in their own right, indeed they may associate themselves with institutions. An institution exists in its own right. A course may exist in its own right (what if the same course is offered at more that one institution, are they the same?)... The domain expert would best advise on that (infact they should advise and guide the entire design).
If you make an aggregate too big you will run in to concurrency issues that can avoided if you find the right model.
Some PDFs I recommend reading are here:
http://dddcommunity.org/library/vernon_2011/
So I'm working on an assignment for school, where I am to model (using a domain model) a web shop that delivers complete grocery bags to people's homes. (http://www.linasmatkasse.se). I wish I could be more specific here, but this is all I have unfortunately.
I haven't received any use case, but the scenario would be something like, add bag to cart, create account/add info, pay.
This is what I have so far : http://i.imgur.com/BIljBtj.png?1
Are there any redundancies? (I only have to depict the model of the site, unsure how much to include).
Could/Should I add composition between for instance Customer and Account, Cart and OrderLineItem, Order and Cart?
Pretty uncertain about attributes & multiplicites in general. Any feedback or support here is appreciated.
Payment class? Is it needed? Should it have payment methods included?
Should I model human elements like support?
Should I model more of the delivery
Is association between customer and order needed?
Thanks a bunch! Again...
It should be a class diagram. So, such verbs as "has", "contains", should be shown as aggregation, "supplies", "describes", "makes" should appear on associations arrows only if these names are the names of the attribute in the source(for arrow) class. "owns" should be shown as a dot on the end of association. Also put attribute names really on ends of the associations. You can name the whole associations, but that implies, that the association itself, without the instances of the classes, somehow exists. If you want to write comments, they are to be placed on the notes. But normally that words as "supplies", "describes", "makes", "has", "contains", "owns", appear on the Use case diagram. Make it apart from the class diagram, if you want to think on this logic or discuss it with a client or a sales manager you work with.
Composition
That one between Account and Cart you have made very nicely. Thus you cay, that Cart doesn't exist out of its Account and any account has only one cart. So, the composition with multiplicity 1 to 1 is sensible and bears a lot of important info.
The customer as you made it, is useless. You need only Account.
Till now I don't understand the use of OrderLineItem and ItemList. If the use of some classes is not obvious, it is bad - at least put comments there or think, if you really need them.
Payment - yes, it is necessary. As for payment methods, put them in the specific Enumeration class block, name them there as items and connect Payment to PaymentMethods.
No human elements here! You are deep into the IT model, on the border of coding. You really want to do a use case diagram, don't you?
Delivery? Maybe more enumerations for way of delivery and supplier, ClientAddress that is seen from Account, Order. It is for you to decide if you want to cover this or that scope.
ItemDescription should be connected to Item only
All you associations are navigable in both ways. It is senseless. Choose the navigability.
If a class attribute is an instance of another class, put a dot on that another end of association (end owned by classifier).
Supplier connected to Order? Do you want to cover the theme of trade with suppliers, too? Then there should be more classes on that theme. And it could be another component and another class diagram. Or is there a graphic error?
Generally in UML, you model roles as opposed to people however if there is a use case to model people (along with their names, contact details, etc), is there a known way of depicting this?
For example do I create a superclass called "Person" and generalize the roles followed by a specialization of a real person?
I took a look at some of your other questions and now I realise I completely misunderstood and you're probably trying to model an organization and the people in it.
ArchiMate is a semantic layer on top of UML that is intended for architecture modelling. Real people get described in the business layer, as actors.
A business actor is defined as an organizational entity capable of (actively) performing behavior.
A business actor performs the behavior assigned to (one or more) business roles. Examples of business actors are humans, departments, and business units. A business actor may be assigned to one or more business roles. The name of a business actor should preferably be a noun.
Now generally the person fills a spot in the organization that in a couple years could be filled by another person. The structure / architecture of the organization would not change and as such the actor can be described by the name of their position, say, "Head of department" rather than by their name and phone number.
Still, I understand that it may be handy to have this sort of information available when you want to contact them.
UML-model-wise, I'd think that the actor Head of Department is a class, realizing a business role that's also a class, and that Joe with phonenumber 12345 is an object of that class.
But practically, I'd think this is too much detail for the level at which you're describing the organization. I'd suggest you stick a UML note on those few actors of key contacts whose names you think are worth mentioning in the diagram. But administrate the rest of them in a system that's more fit for this, like your company's ADS or Contacts in Microsoft Outlook.