Identifying bounded contexts for meal planning app - domain-driven-design

I'm designing meal planner app. I want it to has:
typical cookbook with recipes (recipe can be added to cookbook by user, it contains list of ingredients with thier amounts, servings amount, calories amount calculated based on ingredients, ingredients can be added to shopping list and recipe itself can be added to meal plan). Recipes can be searched by some filters like cuisine type etc.
meal planner - modifiable list of recipes for every weekday
ingredients catalog - ingredients can be searched by filters, every ingredient some values e.g. calories. Perhaps it would has calculator for measurement (something like how many grams is in spoon of flour)
shopping list - list of ingredients added from recipes or manuanly by user, they can be removed and their quantity can be modified
As for architecture I want it to be microservices based app. I have read some books like Building microservices, Domain-driven-design quickly and bunch of articles and tutorials. However I can't figure out how to slice domain to identify bounded contexts which would be microservices.
All what came to my mind is division like I pointed cookbook, planner, ingredient catalog, shopping list but I'm not sure if it's good start for models designing in my app. I'm newbie and I would like to have some advices or ideas from someone who is into designing such things.

I'm designing meal planner app.
As for architecture I want it to be microservices based app.
Services tend to be focused on do-ing rather than be-ing. Publishing a cookbook is one workflow, meal planning is another workflow, and so on.
An important idea in services is that they should be autonomous. There are a number of different ways to understand autonomy, but the one I find helpful is to consider that we copy data from producers to consumers so that the consumers can continue to do useful work even when the producer is unavailable.
For your example, meal planning needs a copy of a published cookbook. But it doesn't necessarily need today's cookbook -- a copy of yesterday's cookbook could be fine. We could achieve this if we had some asynchronous messaging that carries copies of the information from one service to another.
However I can't figure out how to slice domain to identify bounded contexts which would be microservices.
Right - that the hard part, especially when you don't have enough experience in the domain to know what the different processes are, which live data they share, which stale data they share, and so on.
The good news is that if you don't already know the answers to that, it's probably because the volume of information you need to handle right now is small enough that you can do it all together. In other words, first focus on deploying your domain model in a monolith, and iterate on the boundaries of the autonomous modules within it - paying special attention to which processes need to share live copies of the same data, and which processes can use stale copies of data.
Design your persistence model so that features never need to look in somebody else's table (information is copied, not shared). Make sure that the communication between modules satisfies location transparency, so that moving a component somewhere else doesn't break the world.

Related

Class diagram for a mini JEE project

I want to start a project in JEE and I need to confirm about my class diagram. I need to know if the methods used are correct and if the composition I used is correct or not.
This is my class diagram:
The project is about an online sales store, that wants to set up a management tool to sell products, and to manage its products. This tool must include the following features:
Identification module: identification of clients, managers, supervisors
Sales module: make purchases for users
Product Management Module: Adding / Deleting Products
Statistical module: visualization of sales statistics
Functional Specifications
It is necessary to act on the application, to connect to the application with a user ID and password. To facilitate its use and in order to avoid any mishandling thereafter, here is the solution:
User Profile:
The user will be able to visualize the products sold by My Online Races. The user can place an order, provided that he has registered with the site My Online Races.
Manager profile:
The manager will be able to manage the products:
Add / Edit / Delete Products
Add / Edit / Delete category
These data insertions can be made using CSV or XML files, but also through various forms on the website.
The manager will be able to view the sales statistics.
Supervisor Profile:
The supervisor can add managers whose roles are specified above.
The supervisor will be able to view the sales statistics.
The supervisor will be able to view all the actions performed by the managers, a sort of audit trail.
Well I wish to know already if you have remarks about my design. As well as I have a confusion for several methods, for example adding, modifying and deleting a product. Should I put them in the manager or product class? Is the composition I put correct or should I remove it?
Quick review of the diagram and advices
First some minor remarks about class naming: Ordered should be called Order.
The composition between Article and Order is just wrong (not from a formal view, but from the meaning it conveys). Use a normal one-to-many association: it would reflect much better the real nature of the relation between the two classes. Please take into account that a new article may exist without having been ordered, so it shoud be 0..* instead of 1..*
+belongs and +do in the middle of an association are syntactically incorect. You should use a plain triangle instead (or nothing at all). The triangle should be oriented in the reading direction Person do |> Order and Article belongs to |> Category
The methods seem ok. You do not need to add a suffix.
How shall objects be managed (created/updated/deleted) ?
A more advanced concern is not about the diagram but about how you want to organise persistence (i.e. database storage):
do you really want the object to be an active record, that is an object that adds, updates and deletes itself (to the database) ? It's simple to set up, works well, but makes the class dependent on the underlying database implementation and thus makes maintenance more difficult;
or wouldn't it be better to use a repository for each object ? In this case the repository acts as a collection that manages all the database operations. The domain object (Article, order, User, ...) then have nothing to know about the database, wich leads to more maintainable code.
But this is a broader architectural question. If it's just for a first experimental project with JEE, you can very well use the active records. It's simpler to set up. Be sure however in this case to disambiguate the Add/Update/Delete on Person, since it currently may give the impression that any person can add anyone.
Improvement of the model
A final remark, again not about the diagram itself, is about the domain. Your model considers that an Order is about a single Article.
In reality however, orders are in general about one or several articles: if this would also be the case here, your Order would become an OrderItem and the real Order would be inserted between Person and OrderItem. You could then make the relation between Order and OrderItem a composition (i.e: OrderItem is owned by Order, which has responsibility for creating its items, and the items have no sense without the related order).

DDD Composing Multiple Bounded Contexts

I would like your advices about bounded contexts integration.
I have a usecase which put me in a corner :
I have a bounded context for Contract management. I can add parties (various external organizations for example) to a contract. Select for each party their investment / contribution (ex: 10% of the total). SO contract management is two-fold : one is administrative (add party, manage multiples dates, ...) the other one is financial (plan their contributions that span multiple years, check contributions consumption, ...).
I have another bounded context for Budget. This context is responsible for expenses management at the organisation level. Example: a service A will have 1000 € of expense capacity. We can plan a budget and after that each organisation party can consume, buying stuff, their part. In order to build a budget, the user in charge of the enterprise budget can allocate money directly or integrate a yearly contract financial component. When we integrate a contract part inside the budget we froze the data inside the budget, i.e we copy the monetary data from one database table inside another one (adding some audit informations). We have a single database.
It is this last part I struggle with. Each bounded context is a dedicated application. In the budget application, after a contract part has been integrated inside the current budget, I need to display the budget details lines. Unfortunately in the budget tables I have only the money data and not some basic info about the contract (object, reference, ...).
What am I thinking :
sometimes is not bad to duplicate data between bounded contexts. I froze the money part of a contract. I can also freeze / duplicate the object and reference of the contract. Then the querying will only take place inside the budget context. But what is problematic here is the data duplication. Today I need object /refrerence and if tomorrow I need more fields ... I will need domain events management to keep the data between contract / budget in sync.
querying budget and for each line query a contract service that will return the data needed. That keep each context autonomous but I need to make lots of database requests to enrich the budget details line objects.
with only one join at the database level we can make this work. What about coupling here ? It is the simple solution and what we are doing today (is it a shared kernel ?). It seems we can't afford to change contract structure without rebuilding the budget application. I don't have a programmatic contract between the contexts.
My question is :
How can I build this UI screen that need data from the budget context and each details line need data from the contract context ?
Side Notes :
Perhaps the contexts identification and perimetre are wrong from the start (it is a legacy design).
What I would like is to keep the context separate (loose coupling). If we can specify design contracts between the contexts, the maintenance is easier (or not ?).
I failed to see how to integrate these contexts (I need to re-read shared kernel, ustream / downstream etc).
This is an additional, distinct bounded context. It has some overlap with the existing bounded contexts, which can easily lead you down the wrong path (merging contexts or putting additional behaviour in a context where it doesn't belong).
Sometimes it's OK to have entities in different bounded contexts which are referring to the same logical entity, but which are just providing a different view of that entity for the purposes of a specific scenario (eg in a specific context).
A good example of this is in an e-commerce scenario. In most e-commerce applications you will have the concept of an Order, but there is no global, definitive notion of what an "order" is. In a finance context - the order is simply an invoice. In a fulfilment context - the order is simply a packing list and an address to send the goods to. In a marketing context - the order represents a little piece of intelligence about what the customer is interested in, which can be used for future targeted marketing.
There is a thread of commonality which runs through all of those entities, but you would likely see at least 3 separate Order classes, each one capturing the concept of an order within a context.
And so in your case, you have a bounded context for Contract and a bounded context for Budget. It seems to me that you now have another way of looking at these entities, and specifically the way in which they interact with each other. This is a new view of the entities, a view which can be captured in its own context. This new context will likely have its own Contract and Budget entities, and there will be overlap with the Context and Budget contexts, but there will also be additional relationships and behaviour in there, which wouldn't make sense in those other contexts.
This is a really difficult idea to explain :) I wrote an answer to a similar question some time ago here: DDD - How to design associations between different bounded contexts

Service Layer DTOs - Large Complex Interactive Report-Like Objects

I have Meeting objects that form the basis of a scheduling system, of which gridviews are used to display the important information. This is for the purpose of scheduling employees to meetings, and for employees to view what has been scheduled.
I have been trying to follow DDD principles, but I'm having difficulty knowing what to pass from my service layer down to presentation area of system. This is because the schedule can be LARGE, and actually consists of many different elements of the system. Eg. Client Name, Address, Case Info, Group,etc, all of which are needed for the meeting scheduler to make a decision.
In addition to this, the scheduler needs to change values within this schedule and pass it back up to the service layer (eg. assign employees from dropdowns, maybe change group, etc). So, the information isn't really "readonly" - it needs to be interacted with. ie. It's not just a report.
Our current approach is to populate a flattened "Schedule Object" from SQL, which is constructed from small parts of different domain objects. It's quite a complex query. When changes have been made, this is then passed back up to the service layer, and the service will retrieve the domain objects in question, and fire business methods on the domain objects using information from the DTOs.
My question is, is this the correct approach? ie. Continue to generate large custom objects from SQL, and then pass down from Service Layer to Presentation Layer objects that feel a lot like View Models?
UPDATE due to an answer
To give a idea of the amount entities / aggregates relationships involved. (this is an obfuscated examples, so relationships are the important things here)
Client is in one default group
Client has one open case but many closed
Cases have many Meetings
Meeting have many assigned Employees
Meeting have many reasons
Meeting can get scheduled to different groups
Employees can be associated with many groups.
The schedule need to loads all meetings in open cases that belong to patients who are in the same groups as the employee.
Scheduler can see Client Name, Client Address, Case Info, MeetingTime, MeetingType, MeetingReasons, scheduledGroup(s) (showstrail), Assigned Employees (also has hidden employee ids).
Editable fields are assign employee dropdowns and scheduled group.
Schedule may be up to two hundred rows.
DTO is coming down from WCF, so domain model is accessed above this service layer, and not below.
Domain model business calls leveraged by service based on DTO values passed back, and repositories deal with inserts/updates.
So, I suppose to update, is using a query to populate an object which contains all of the above acceptable to pass down as one merged DTO? And if not, how would you approach it? ( giving some example calls to service layer, and explaining a little bit about how you conceive the ORM fetching the data keeping in mind performance)
In the service layer and below, I would treat each entity (see aggregate roots in DDD) separate with respect to it's transactional boundary. I.e. even if you could update a client and a case in the same UI view, it would be best to transactionally modify the client and then modify the case. The more you try to modify in one transaction, the more you can conflict with other users.
Although your schedule is large and can contain lots of objects, the service layer should again deal with each entity (aggregate root) separately and then bundle them together into a new view model. Sadly, on brown-field projects, a lot of logic might be in the SQL and the massive multi-table joins might make this harder to refactor into more atomic queries that do exactly what is needed. The old-school data-centric view of 'do everything you can in the database' goes against everything DDD.
Because DDD is a collection of design ideas and patterns and not particularly a methodology or an architecture, it sounds that it might be too late to try shoe-horn your current application into a DDD application-centric design. It sounds as though your current app is very entrenched in the data-centric view.
If everything is currently being passed up through the layers in one monolithic chunk, it might be best to keep with this style and just expose these monolithic chunks to the people in the other team who wish to consume them, for use in their new app. You might be able to put some sort of view model caching in place (a bit like the caching view model element in CQRS).
In my personal opinion, data-centric, normalised data apps have had their day (they made sense in the 1970s when hard disk space was expensive) and all apps should be moving toward more modern practices. In reality, only when legacy systems are crawling on their knees, will stakeholders usually put up the cash to look for alternatives (usually after stuffing every last server with RAM). It might be possible or best to convince them to refactor small sections at a time.

DDD modeling 1:1...N relationships with query performance in mind

I'm a DDD beginner, and I have a legacy project which would surely benefit from a proper domain layer. The application has to be modified to support multiple application and UI layers. The domain logic is at the moment implemented using the transaction script pattern. Basically I inherited a DB structure which is not allowed to be altered, the new application should be a drop in replacement of the old one.
I stumbled upon an interesting modelling problem in a small part of the domain, which I'm sure experienced DDD practitioners will find interesting. I can't be too specific about the problem, so I'll describe a problem which closely matches mine.
Problem description
Let's suppose we should manage a collection of products. Products are identified by ids, they contain some description, and every product has a few images associated with it. Here comes the tricky part. The images, their contents, are physically stored in the DB, so they are huge chunks of data. (let's just ignore now how good or bad is storing images in a DB, it's just an example). There are some invariants that must be enforced on adding/editing/removing products.
Adding products
A product is only valid if it has images associated with it, without adding images a new product should not be allowed to be entered
Every product must be associated with exactly 5 images, no more, no less.
The order of images associated with the product must be maintained
Editing products
Images of existing products can be replaced, but the number and order of the associated images should be maintained
Removing products
When a product is removed, all of the images associated with it should also be removed
Considered solutions
The class diagrams of various solutions
Solution 1:
The simplest way to model these concepts would be the following.
The Product is the AR. The Images associated with the Product can be accessed and modified through the Product, so Product is responsible for enforcing the 5 Images rule. The advantage of this approach is that invalid Products can't be created or edited in a way to make them invalid, and no Images will be left behind when a Product is removed. So the aggregate if formed around the transaction boundary. The problems with this approach is that in the vast majority of cases the UI would just need to present the list of products, and maybe to modify their description. The UI would very rarely need to display or modify the Images associated with the product. So 95% of the cases huge amounts of unnecessary data would be loaded into the memory.
Lazy loading? The domain model should be implemented in a language which doesn't have ORM tools with lazy loading support. Implement my own lazy loading mechanism? The domain objects shouldn't be aware of the way they're persisted or if they're persisted at all. Instead Solution 2 is recommended by Vaughn Vernon.
Solution 2:
The querying performance problems can be solved with this approach by favoring small aggregates and following the reference other aggregates by identity rule. Vaughn Vernon has a great series of articles describing how to achieve this.
The aggregate is split into two parts Product and ImageSet. Both of them are referencing ProductId as a value object. The Product would be responsible for enforcing the no product without Images rule, and the ImageSet would enforce the no ImageSet without 5 images rule. Querying is not a problem anymore, the ImageSet would be retrieved only when it's needed by a service.
However, this problem is a lot more complex then what Vernon describes in his articles (0...N association). The problem is that the creation of a Product would lead to modifying or creating 2 aggregates, which eliminates the purpose of modelling aggregates around transaction boundaries. The service which adds the new Product would be responsible for transaction management.
Solution 3:
The final solution would be the use of bounded contexts. So for simplicity we name them BC1 and BC2. In BC1 a Product would just contain the ProductDetails. Services interested in querying Products for their details and maybe modifiyng them would use BC1 (ProductRepository in BC1 wouldn't allow adding or removing products, just querying/modifying existing ones). In BC2 a Product would contain the ProductDetails and the Images associated with it. So services interested in adding/removing products, and modifying/retrieving their images would use BC2. Commmon value objects and entities would be shared between these 2 BCs.
This solution would solve all the transactional consistency and querying performance problems. However, I'm not sure based on their definition BCs should be created in response to these kinds of problems.
I'm sorry for the long question, but I feel I should really point out which kinds of solutions I've already considered. And sorry for the linked images, I'm not allowed to upload images yet.
An important observation in your use-case is that the problems of the 1st solution are isolated to the query side of the application. There is no reason to use the same model for processing commands and enforcing constraints as the model used for queries. The read-model pattern can be used to separate the reads from the writes which would allow you to create specific read-models for specific UI requirements and the read-model won't affect your domain model. While it is tempting to utilize the same model for reading as the one for writing, especially given that most ORMs support intricate queries and given the DRY principle, in practice it is much easier to separate the read model from the executable domain model.
Also, the series of articles by Vaughn Vernon are a great resource for understanding intricacies of aggregate design, however the central focus of the articles is on how to partition aggregates based on behavioral requirements not query requirements.

DDD: Organizing 100s of properties on an Entity

How would you organize an entity that has 100s of properties? One could go as far to say 100s of properties, with a few Value Objects (as a few of the properties have 2 or 3 properties of their own). But the point is, how to handle the large number of properties.
I am re-creating our model from the ground-up using DDD, and the current issue is how to organize one of main entities that is broken up into many many many subsets. Currently it was written to have about a dozen sub-sets of properties. Like CarInfo() with 50+ properties, CarRankings() with 80+, CarStats(), CarColor(), etc, etc.
Think of it as mass-data stored on a single entity root.
Is it appropriate to have a service for the simple purpose of grouping a large collection of properties? Like CarInfoService that would return a Car() object, along with a large collection or sort.
Another idea would be to look at how the data is displayed. There is no one view that shows all of this data. Instead, they are split up based on their subjective matter. Like CarInfo shows all information about the car. Another would be CarStats that shows all stats of the car. So in this sense, the Application layer can build the underlying details needed for the UI. But, I still need a way to store it in the domain.
I have a mind to just put a number of xml property bags on it and call in the day. lol
This is a tough problem. You've got an aggregate root with lots of branches. But it sounds as if your users only work with certain collections at certain times. You could try pruning the tree a bit.
For instance, in your Car example, if your users are comparing the rankings of different cars, you could treat that as its own module or subsystem. No need to load up the detailed car data associated with each ranking, if the specific task is to figure out which ones rate better than others.
Remember, even though the data may be stored in a parent-child hierarchy in the database, it doesn't necessarily mean your domain will be structured in the same way.
By looking at the tasks or functions your users will perform on your data, you might discover concepts that help to break up that giant aggregate into more manageable chunks.
If you do need to assemble the full root with all of its branches, I think you'll definitely want some sort of service to bring everything together.
I think you should consider to split such an entity in different bounded contexts related via shared idenfitiers. Thus you will have different Cars in different BCs (thus different namespaces, too), and each one will handle only the informations that are related to that particular aspect.
This way, in case of deeper insight, chances are that you will have to refactor only a BC without affecting the others.

Resources