I'm studying the book that forms the bases of DDD, and I'm a bit stuck on understanding the example about Cargo Shipping, in chapter 7.
More specifically, I have following question; Wat is the real purpose of "Delivery History"? In my understanding, it is just a collection of handling events. But if that is the case, why does it have its own entity object? Especially since completion time is part of the Handling Event, I fail to understand the added value in Delivery History...
Any help from smarter people than me is greatly appreciated..
Tom
The use of Delivery History is to provide a type of log. Like when you track a parcel online, you can look at the last entry in the Delivery History and this is the last event that happened in the story of delivering the cargo.
In the real-world, a company may phone the shipping company and say "Where is my cargo? It was supposed to be delivered last Tuesday!", an operator can use the software to find the cargo and from the Delivery History the operator can discover from looking at the last entry, that the cargo is delayed in transit, etc.
Evans also states that the delivery can be considered complete when the Delivery History matches the goals of the Delivery Specification. This information is important, so it needs to have business logic around it to ensure the information is correct, valid and most importantly it needs to be persisted. This is why Delivery History is an Entity.
Delivery History reflects what has actually happened to a Cargo, as
opposed to the Delivery Specification, which describes goals. A
Delivery History object can compute the current Location of the Cargo
by analyzing the last load or unload and the destination of the
corresponding Carrier Movement. A successful delivery would end with a
Delivery History that satisfied the goals of the Delivery
Specification.
--- Eric Evans, Domain-driven Design: Tackling Complexity in the Heart of Software
EDIT
On the Cargo class diagram, it does look as though the Delivery History class has references to the Handling Events. In this case, the Delivery History might exist as to:
Provide a nice place to put the business logic for querying the
delivery history.
It might preserve a common term (and possibly physical artifact) used
in the Ubiquitous Language of the cargo handling domain.
The Delivery History also has access to Carrier Movement events, so it
knows when the Carrier has arrived at it's destination port, etc.
To put Delivery History specific code in the Handling Events would violate the Single Responsibility Principle.
Related
I have a list of functionality that the system should have and I have created a case diagram for it, but I am not sure if it correspond to said functionality and want a second look on my solution. Hopefully it is readable and I appreciate any feedback on my trail of design.
Description of said functions:
The system shall allow people to register as a student or faculty member. To sign up, users must provide their name, e-mail address, phone number, and a password. In addition, students add the name of their program and their student id; faculty members add the name of their department and their employee id.
A user shall be able to search for books, the library system shall indicate the availability for books. If available for loan, a logged in user shall be able to reserve a book for loan. When reserved, the librarian will move the book to a pick-up shelf. To loan a book, users shall login at the library in person, and checkout the books.
The library has an automated booth where users can leave the books and the system shall process the return, upon return, the system shall send a digital receipt sent to their e-mail address.
When a book is not returned in time, the system shall send a reminder e-mail with a fine for each day it is late.
The system shall allow users to extend the loan period of a loaned book at most two times. The system shall allow users to have at most five books on loan simultaneously. If a book is not available in current library, but is in another one, users can ask the system to transfer and vice versa. Books have a title, author, ISBN, edition, and shelf number denoting their location in the library. The library has varying stock for different books, it has a single copy for most books but up to ten physical copies for some popular books.
Librarians shall be able to add new books to the system and edit the information of existing books.
The design :
Update based on feedback:
I will not make a detailed review of your diagram, since this is very specific to your needs and will not help anybody else. However, I'd like to address some general issues that are frequent in these kind of diagrams:
It appears in the requirements that users may be a student or faculty member (or both?), whereas your diagram suggest that a user is another independent category of actors.
Having several actors for a use case is ambiguous. It cannot always be avoided, but here, it's not clear if all the actors are involved at the same time for a search, or if they are involved one after the other, or if only one may be involved at a time.
Your diagram is a functional decomposition of the requirements. For example, Register and Verify registry are not independent, but the second belongs to the detailed decomposition of the first, without being an independent user goal (in fact, the verification doesn't make sense without the first). The same applies to all the verifications ("maximum...") as well. This is not forbidden but strongly discouraged as it leads to too detailed and complex diagrams.
Sometimes your diagram seems to be a sequence of action: e.g. Return a book is followed by a confirmation email. Use-case diagrams shall not show any sequence. If you want to show the workflow, you need to use an activity diagram and not a use-case diagram.
extend corresponds to an optional use-case. Here, you seem to say that books are returned only for some loans.
In conclusion, simplify your diagram to show only user goals. Avoid extend and include dependencies as much as possible, to keep it simple and understandable. If you want to document details, document them in a narrative, not in the diagram.
To boil it down: this is no use case synthesis but functional decomposition. Use cases show added value for actors. Full stop. This is obviously the hardest thing to learn when finding use cases. They are like pearls you have to find. It's not about the how-to.
I recommend reading Bittner/Spence about use cases.
I'm currently working on a CMMS software. Most of these packages have some way of managing your inventory, being able to create Purchase Orders to buy more stock, etc.
Part of our system works perfectly with Event Sourcing because there are clearly defined events. But there is also a bunch of attached data that are almost completely unrelated to that whole process and are just used by companies for reporting at a later date.
For example, a Purchase Order might have a department attached to it. We don't use this department in any stage of the Purchase Order, but a company might come along and want a report for 'How much money has each department spent'. On the other hand, another company might be so small/specialized they doesn't even have separate departments so it doesn't care about it.
That's just 1 example, but there can be a decent amount of fields like that (Think 5-10 per Entity). In this kind of situation, is it better to just have a 'PurchaseOrderUpdated' event that covers all these fields? Or is it considered better to have an individual update events like 'PurchaseOrderDepartmentChanged'?
I personally think there should be an event per property, but I think the rest of my team would complain about having to set up that many events.
It sounds like you may be mixing up two different approaches.
An event in an event sourced system describes a change in state that HAS already happened. This is typically triggered by a command issued to (typically) an aggregate root. A key feature of these domain objects is that they don't have any public properties. It wouldn't therefore make sense to create an 'Update' per property. Here is a blog post which talks about how events are names and used:
6 Code Smells with your CQRA Events - and how to avoid them
Regarding the payload of an event. I have found it better to ensure events are rich in data. A key value of doing event sourcing is the ability to create new read models that you hadn't considered when you initially built the system. Or as you rightly pointed out, create invaluable reporting for the business. IMHO make rich events which include contextual information as well the key information about the state change.
A better way to think about events is that they are transactional boundaries. So if by default you have a potential to update a few fields, you shouldn't need to emit more than one event. For this event-based thinking, event modeling helps communicate this with the rest of the organization: https://eventmodeling.org/posts/what-is-event-modeling/
I am new to DDD. Now I was looking at the domain event. I am not sure if I understand this domain event correctly, but I am just thinking what will happen if domain event published failed?
I have a case here. When a buyer order something from my website, firstly we will create a object, Order with line of items. The domain event, OrderWasMade, will be published to deduct the stock in Inventory. So here is the case, what if when the event was handled, the item quantity will be deducted, but what if when the system try to deduct the stock, it found out that there is no stock remaining for the item (amount = 0). So, the item amount can't be deducted but the order had already being committed.
Will this kind of scenario happen?
Sorry to have squeeze in 2 other questions here.
It seems like each event will be in its own transaction scope, which means the system requires to open multiple connection to database at once. So if I am using IIS Server, I must enable DTC, am I correct?
Is there any relationship between domain-events and domain-services?
A domain event never fails because it's a notification of things that happened (note the past tense). But the operation which will generate that event might fail and the event won't be generated.
The scenario you told us shows that you're not really doing DDD, you're doing CRUD using DDD words. Yes, I know you're new to it, don't worry, everybody misunderstood DDD until they got it (but it might take some time and plenty of practice).
DDD is about identifying the domain model abstraction, which is not code. Code is when you're implementing that abstraction. It's very obvious you haven't done the proper modelling, because the domain expert should tell you what happens if products are out of stock.
Next, there's no db/acid transactions at this level. Those are an implementation detail. The way DDD works is identifying where the business needs things to be consistent together and that's called an aggregate.
The order was submitted and this where that use case stops. When you publish the OrderWasMadeevent, another use case (deducting the inventory or whatever) is triggered. This is a different business scenario related but not part of "submit order". If there isn't enough stock then another event is published NotEnoughInventory and another use case will be triggered. We follow the business here and we identify each step that the business does in order to fulfill the order.
The art of DDD consists in understanding and identifying granular business functionality, the involved aggregates, business behaviour which makes decisions etc and this has nothing to do the database or transactions.
In DDD the aggregate is the only place where a unit of work needs to be used.
To answer your questions:
It seems like each event will be in its own transaction scope, which means the system requires to open multiple connection to database at once. So if I am using IIS Server, I must enable DTC, am I correct?
No, transactions,events and distributed transactions are different things. IIS is a web server, I think you want to say SqlServer. You're always opening multiple connections to the db in a web app, DTC has nothing to do with it. Actually, the question tells me that you need to read a lot more about DDD and not just Evans' book. To be honest, from a DDD pov it doesn't make much sense what you're asking.. You know one of principles of DD: the db (as in persistence details) doesn't exist.
Is there any relationship between domain-events and domain-services
They're both part of the domain but they have different roles:
Domain events tell the world that something changed in the domain
Domain services encapsulate domain behaviour which doesn't have its own persisted state (like Calculate Tax)
Usually an application service (which acts as a host for a business use case) will use a domain service to verify constraints or to gather data required to change an aggregate which in turn will generate one or more events. Aggregates are the ones persisted and always, an aggregate is persisted in an atomic manner i.e db transaction / unit of work.
what will happen if domain event published failed?
MikeSW already described this - publishing the event (which is to say, making it part of the history) is a separate concern from consuming the event.
what if when the system try to deduct the stock, it found out that there is no stock remaining for the item (amount = 0). So, the item amount can't be deducted but the order had already being committed.
Will this kind of scenario happen?
So the DDD answer is: ask your domain experts!
If you sit down with your domain experts, and explore the ubiquitous language, you are likely to discover that this is a well understood exception to the happy path for ordering, with an understood mitigation ("we mark the status of the order as pending, and we check to see if we've already ordered more inventory from the supplier..."). This is basically a requirements discovery exercise.
And when you understand these requirements, you go do it.
Go do it typically means a "saga" (a somewhat misleading and overloaded use of the term); a business process/workflow/state machine implementation that keeps track of what is going on.
Using your example: OrderWasMade triggers an OrderFulfillment process, which tracks the "state" of the order. There might be an "AwaitingInventory" state where OrderFulfillment parks until the next delivery from the supplier, for example.
Recommended reading:
http://udidahan.com/2010/08/31/race-conditions-dont-exist/
http://udidahan.com/2009/04/20/saga-persistence-and-event-driven-architectures/
http://joshkodroff.com/blog/2015/08/21/an-elegant-abandoned-cart-email-using-nservicebus/
If you need the stock to be immediately consistent at all times, a common way of handling this in event sourced systems (can also in non-event based systems, this is orthogonal really) is to rely on optimistic locking at the event store level.
Events basically have a revision number that they expect the stream of events to be at to take effect. Once the event hits the persistent store, its revision number is checked against the real stream number and if they don't match, a conflict exception is raised and the transaction is aborted.
Now as #MikeSW pointed out, depending on your business requirements, stock checking can be an out-of-band process that handles the problem in an eventually consistent way. Eventually can range from milliseconds if another part of the process takes over immediately, to hours if an email is sent with human action needing to be taken.
In other words, if your domain requires it, you can choose to trade this sequence of events
(OrderAbortedOutOfStock)
for
(OrderMade, <-- Some amount of time --> OrderAbortedOutOfStock)
which amounts to the same aggregate state in the end
I am working on some software modeling/design homework and I'm having trouble wrapping my head around how to turn this particular use case into a Collaboration diagram. I found this excellent tutorial, but the use case I am studying introduces a "UI" component that I can't find an analogy for.
The problem in question is quoted:
Use case name: Report Emergency
Participating Actors: Initiated by the officer and communicates with correspondent
Flow of Events:
The officer activates the “Report Emergency” function of her terminal
System responds by presenting a form to the officer
The officer fills the form by selecting the emergency level, type, location, and
brief description of the situation. The officer also describes possible responses to
the emergency situation. Once the form is completed, the field officer submits the
form.
System receives the form and notifies the correspondent.
The correspondent reviews the submitted information and creates an incident in the
database. The correspondent selects a response and acknowledges the report.
The system displays the acknowledgement and the
selected response to the officer.
Precondition: The officer is logged into the system
Postcondition: The officer has received an acknowledgement and the selected response
from the correspondent, OR the officer has received an explanation indicating why the
transaction could not be processed.
As I understand it, associations in a Collaboration diagram indicate the flow of messages between objects, and don't necessarily reflect the physical relationship between what the objects model. If that's the case, then which object should be responsible for the newEmergencyForm() method, and which object should be calling that method? Couldn't the newEmergencyForm() method and the reportEmergency() method be rolled up into one?
Now (current UML standard is 2.4.1) the diagram is called Communication diagram, not collaboration one. Collaborations remain as elements of some diagrams, but they have other sense.
As I understand, Report Emergency is filling the form. And newEmergencyForm is providing the form to be filled. These are two different actions, you already know the difference between them, so, you have no need in not noticing this difference and counting them for one operation. But if for some reason you wish to postpone showing the subject for later diagrams, you may do it. It is NOT against standard.
I wouldn't name the things that create these messages 'objects'. On this level of abstraction we rather speak on components.
You can't say what component creates some message until you define all components. You can do it in head, it is OK, but then we cant't help you with the choice. What is 'system'? (on this level we do not talk on system as a whole, it is the term for Use Case. What is çorrespondent'? Is it the same as officer or can be same? Or is it a subsystem? What other components do you have?
Else you have to provide us the Component diagram as a source. BTW, I am almost sure that after correct defining all components you will find the solution yourself.
Sorry, I know this is a very lame question to ask and not of any use to anyone else. I have an assignment in UML due tomorrow and I don't even know the basics (all-nighter ahead!). I'm not looking for a walkthrough, I simply want your opinion on something. The assignment is as follows (you only need to skim over it!):
=============
Gourmet Surprise (GS) is a small catering firm with five employees. During a typical weekend, GS caters fifteen events with twenty to fifty people each. The business has grown rapidly over the past year and the owner wants to install a new computer system for managing the ordering and buying process. GS has a set of ten standard menus. When potential customers call, the receptionist describes the menus to them. If the customer decides to book an event (dinner, lunch, picnic, finger food etc.), the receptionist records the customer information (e.g., name, address, phone number, etc.) and the information about the event (e.g., place, date, time, which one of the standard menus, total price) on a contract. The customer is then faxed a copy of the contract and must sign and return it along with a deposit (often a credit card or by check) before the event is officially booked. The remaining money is collected when the catering is delivered. Sometimes, the customer wants something special (e.g., birthday cake). In this case, the receptionist takes the information and gives it to the owner who determines the cost; the receptionist then calls the customer back with the price information. Sometimes the customer accepts the price, other times, the customer requests some changes that have to go back to the owner for a new cost estimate. Each week, the owner looks through the events scheduled for that weekend and orders the supplies (e.g., plates) and food (e.g., bread, chicken) needed to make them. The owner would like to use the system for marketing as well. It should be able to track how customers learned about GS, and identify repeat customers, so that GS can mail special offers to them. The owner also wants to track the events on which GS sent a contract, but the customer never signed the contract and actually booked a GS.
Exercise:
Create an activity diagram and a use case model (complete with a set of detail use case descriptions) for the above system. Produce an initial domain model (class diagram) based on these descriptions.
Elaborate the use cases into sequence diagrams, and include any state diagrams necessary. Finally use the information from these dynamic models to expand the domain model into a full application model.
=============
In your opinion, do you think this question is asking me to come up with a package for an online ordering system to replace the system described above, or to create UML diagrams that facilitate the existing telephone-based system?
Create an activity diagram and a use case model (complete with a set of detail use case descriptions) for the above system.
I think it's right there in the text: they want you to document the system described.
Best of luck!