I want to display the booking list of a restaurant for a given date. I omit the boundary object here. In the first diagram, the restaurant object maintains the complete set of booking made for the restaurant. In the second diagram, the restaurant object is not used. Are there any benefits using restaurant object?
The main benefit is encapsulation. Different restaurants can handle bookings in different manner. All you have to do is to build common interface for a Restaurant.
Secondly in the former case the BookingSystem immediately have information about the restaurant (and you probably want to present that to either staff or a client). The latter one would have to handle this information in some other way.
If your app is for one restaurant only, then everything that happens in your app is related to that restaurant and this object would not add significant benefit to this design: it could well be made implicit (second diagram).
The drawback is that your app design then relies completely on this underlying assumption. Very often, successful restaurant entrepreneurs open a second and a third venue. Some even become so popular to become a franchise with several thousands of restaurants. So keeping restaurant in the design (first diagram) has the advantage to cover a broader range of needs and easier reuse of the software, at a marginal additional thinking effort. (And the app could be more reusable and interest successful restaurant owners who would not consider it if you'd be mono-restaurant).
P.S: The * in the booking lifeline is not standard UML. The sequence diagram represent a scenario of interactions between lifelines that each represent an individual object. The communication diagram, a close cousin of the sequence diagram, has a * notation, but for the message numbering and not for instances either. Usually, in sequence diagram, a loop fragment is used to show an iteration. More about this topic in this other question
Related
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.
I wondered if anyone could let me know whether this diagram is approximately correct?
I am depicting a database booking system and am very confused about the relationships between some of these use cases. I am fairly sure that I should include them on the same diagram but unsure whether some of my actors (Vet / Nurse) should be on the right hand side because they are kind of end-users whilst also being first users (sorry can't recall the term).
So when you modeling a Use case diagram, you have to realize that you can only approach for describe the functional requirements of the system.
Your system is treated as a blackbox-that is, dealing with what the system does in response to the actor's inputs, not the internals of how it does it. And use case always starts with an input from an actor.
Before modeling a diagram, you have to identify actors(Primary, Secondary), use cases & use case relationships. Actors are who or what initiates events involved in the task of the use case. Actors are simply roles that people pre objects play.
According to your problem,
A dog owner calls the clinic to make an appointment for a yearly
checkup. The nurse finds the nearest empty time slot in
appointment book and schedules the appointment for that time slot.
in here you can see that two people, dog owner and nurse involving the scenario, but the actual actor who interacts with the system is the nurse.
And the use case is a summary of scenarios for a single task or goal. So, you can see that Nurse is Making the appointment for the dog owner.
So to finally, you have to identify what are the relationships. simply relationships are representing communication between actor and use case or dependencies between use cases.
Dependencies between use cases can be defined by using include & extend relationships.
Include is using for determine to identify common sequences of interactions in several use cases. (Can be extracted and reused)
& extend is using for model alternative paths that a use case might have.And you have to keep in mind that base use case doesn't depend on the extension use case
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.
MAKE RESERVATIONS is the activity and it states the following:
A customer contacts a reservation officer about a car rental.
The customer quotes the start and end dates needed, the preferred vehicle, and the
pickup office.
The reservation officer looks up a prices file and quotes a price.
The customer agrees to the price.
The vehicle availability is checked to see if an appropriate vehicle is available for the
required time at the required office.
If the requested vehicle is available at the nominated pickup office, then it is
reserved for the customer. An entry is made in the vehicle availability registering the
reservation.
The reservation officer issues a rental number to the customer.
A rental agreement is then created in a rental file, including the rental number, the
rental period, the vehicle type and the pickup office.
Exceptions
An appropriate vehicle is not available at the pickup office. The customer is offered
an alternative vehicle.
The customer does not agree to a price and asks for an alternate vehicle and/or
period.
I designed the activity diagram for the activity above yet I don't know whether I have to put the question in the decision node or above on the control flow? In my case, the Agree to Price should it be on the decision node or on the control flow arrow that inputs the node?
As well as that, if a use case only specifies a condition, such as " If a vehicle is available, the customer is offered the vehicle and a price is quoted. If the customer accepts then a rental is initiated." how does the decision node look like?
Moreover, what if there are three different actors, should there be a swimlane representing the actors or can the activity diagram be drawn without one?
The activity diagram for the use case above is posted below
I don't know whether I have to put the question in the decision node or above on the control flow?
They are written in the flow, as you did. In UML the decision node is empty (this is a difference from basic flowcharts, where one would write the condition within the node). Each flow coming from a decision node may be annotated with a guard (i.e. condition). When the decision node is executed, any flow whose guard evaluates as true may be selected for execution (Usually, the conditions of the guards are exclusive, and only one guard may be selected, but that is not a requirement).
As well as that, if a use case only specifies a condition, such as " If a vehicle is available, the customer is offered the vehicle and a price is quoted. If the customer accepts then a rental is initiated." how does the decision node look like?
It looks as in your figure, but there should be an action node for asking the client before the decision node, because the only purpose of the decision node is choosing among several possible flows. No actions are executed as part of the execution of the decision node.
Moreover, what if there are three different actors, should there be a swimlane representing the actors or can the activity diagram be drawn without one?
It depends on what you are modelling, if you have different actions performed by different parts of your system, you may use swimlanes (I recently drawn an example here), but you may avoid swimlines if it is not interesting to model that separation. Normally, the actors would provide input to the system, but they will not be executing actions by themselves.
For instance, your example model the behavior of the reservation officer (which is part of your system) based on input from the customer (the initial quote and agreement) and the customer receives output (the rental number). I recommend that you ask that as a separate question emphasizing on the third actor.
In my current project (e-commerce website), we have different Bounded Context like: billing, delivery or payment in our checkout process.
On top of this, depending on what the customer will buy, the checkout process will be different. So depending on the content of her cart the number of steps in the checkout process can be different, or we won't/will ask her for certain informations.
So should one create a different bounded context for each different type of checkout process ?
For example, the Order aggregate root will be different depending on the checkout process
EticketsOrder (in this context we don't need a delivery address so we won't ask one to the user)
Ticket BillingAddress
ClothesOrder (in this context we need a delivery address and there will be an additional step in the checkout process to get this)
Clothes BillingAddress DeliveryAddress
This separation will imply to create two different domain entities even thought they have similar properties.
What's the best way to model this kind of problem ? How to find the context boundary ?
A bounded context is chiefly a linguistic boundary. A quote from the blue book (highlighted key part):
A BOUNDED CONTEXT delimits the applicability of a particular model so
that team members have a clear and shared understanding of what has
to be consistent and how it relates to other CONTEXTS. Within that
CONTEXT, work to keep the model logically unified, but do not worry
about applicability outside those bounds. In other CONTEXTS, other
models apply, with differences in terminology, in concepts and rules,
and in dialects of the UBIQUITOUS LANGUAGE.
A question to ask is whether the different types of orders created are entirely distinct aggregates, or are they all order aggregates with different values. Is there a need to consider order as a whole regardless of how they were created? I've build and worked with ecommerce systems where different types of orders were all modeled as instances of the same aggregate, just with different settings and there were no linguistic issues. On the other hand, the orders in your domain may be different enough to warrant distinct contexts.
I often consider BC boundaries from the perspective of functional cohesion. If you segregate orders into two BCs will there be a high degree of coupling between them? If so, that may be a sign that they should be combined into one BC. On the other hand, if the only place that the BCs interact is for reporting purposes, there is no need to combined them.
It appears as though you may have missed a bounded context. When this happens one tends to try and fit the functionality into an existing BC. The same thing happens to aggregate roots. If something seems clumsy or it doesn't make sense try to see whether you haven't missed something.
In your example I would suggest a Shopping BC (or whatever name makes sense). You are trying to fit your checkout process into your Order BC. Your Shopping BC would be responsible for gathering all the data and then shuttling it along to the relevant parts.
The product type selected will determine whether a physical delivery is required.
Hope that helps.