Domain Driven Design - Inheritance in ValueObjects - domain-driven-design

User <AggregateRoot>{
name: String;
paymentType: PaymentType;
}
PaymentType <ValueObject> {
//Common attributes
}
Can the above PaymentType(ValueObject) be inherited by these ValueObjects(Subclasses) - Credit, Cash, Cheque ?
There is a domain invariant that says, User can have one PaymentType at a time. Should this go into the User(AggregateRoot) or PaymentType(ValueObject) ?

Can the above PaymentType(ValueObject) be inherited by these ValueObjects(Subclasses) - Credit, Cash, Cheque ?
Maybe. Inheritance is largely an implementation detail.
But it's not clear to me that's the question you are really asking. Your example looks a bit like trying to design a "union type", which is to say a handle that you can use to match different patterns.
Scott Wlaschin has an example of a PaymentMethod union type in his domain modeling made functional slide deck. His blog series on designing with types describes the technique in more detail using other examples.
There is a domain invariant that says, User can have one PaymentType at a time. Should this go into the User(AggregateRoot) or PaymentType(ValueObject) ?
It depends. The code for deciding which state transitions are permitted normally goes into the thing that owns the state (in this example, the User). How we represent state, the actual data structures and so on, often live in Value Objects.
The modeling patterns described in chapter 5 (entities, value objects) and chapter 6 (aggregates, repositories) are just patterns. There are no prizes awarded for applying those patterns most perfectly. The main goal in implementing the domain model is still the same: to produce code designs that can be changed smoothly to match the changing needs of the domain.

Related

UML class diagram, agregation or composition with example

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).

How to Approach Domain Modelling with Polymorphic Entity in Domain-Driven Design?

I am rebuilding a software in accounting. This sofware can handle many types of transactions, e.g. sales, inventory restock, and expenses. I have no background in accounting, but I learned some concepts online. I am trying to model the domain with these principles in mind:
A journal entry consists of several recordings, each of which is either a debit or credit. These recordings' total of debit and credit must be equal (balanced) in a given journal entry
A journal entry must be created based off of a source document. One cannot simply create a journal entry without any reason.
From those, I conclude that there has to be these entities present:
JournalEntry entity, which has many JournalEntryItem value objects. This entity is responsible for keeping all its entries in a balanced state.
SourceDocument entity, which has some information of transactions being made
Both JournalEntity and SourceDocument are each an aggregate root, with JournalEntity referencing to a SourceDocument identity.
Now here is the problem. Source documents that are the basis of journal entry creation, can be different things with different behaviors. For example, an 'expense' source document may consists of list of pair of expense category and expense amount, while a 'sales' source document may consists of related inventories, amount of each inventories, and the price of each inventory per one unit.
This makes me think of another approach in the model:
Create an abstract SourceDocument class, with shared properties like date of creation and identity attribute
Create SalesSourceDocument, ExpenseSourceDocument, etc., that are extended from the abstract SourceDocument
JournalEntry entity will still have to reference SourceDocument identity.
While this can make sense, I don't think this is the best way to model the problem in DDD, specifically because it requires to have an abstract entity.
From the sources I read online about DDD, when encountering such problem where I need an abstract entity, I need to separate it into different bounded contexts. However, I'm not sure if it can be done, because a SourceDocument identity may return a concrete SalesSourceDocument in 'sales' context, but it may also return nothing in 'expense' context.
What is the best way to approach this problem?
I think what's important to recognize here is that the source document terminology is to describe the relationship between a journal entry and a document, from a JournalEntry's perspective. Documents are ARs of their own, which can most likely exist without a journal so why should their abstraction be named after the relationship with another AR?
Source document most likely is a necessary terminology to describe the document relating to a journal entry and chances are it will be part of your model too, but perhaps in the form of a value object such as SourceDocument { id, type }.
That doesn't mean you couldn't have a Document abstraction as well if useful: there's no reason to avoid polymorphism at all cost when it's useful.
I may be wrong with that analysis (all models are wrong anyway), but I just wanted to give you a different perspective on that specific modeling aspect.
I am rebuilding a software in accounting. This sofware can handle many
types of transactions, e.g. sales, inventory restock, and expenses. I
have no background in accounting, but I learned some concepts online.
If you can learn your whole domain online then chances are that it's a generic sub-domain where an off the shelf product can most likely be bought. Rather than going online and try to come up with a model on your own you should be involving domain experts: perhaps your entire vision is wrong here.
Furthermore, given the source documents will most likely live in different contexts, it seems like the Accounting context could be acting as a supporting BC that doesn't have explicit knowledge or dependency on other BCs.
What is the best way to approach this problem?
Treat your separate use cases as separate until you discover domain concerns that require aligning them.
Your sales documents and your expense documents are different things, and your data model should reflect that: the information associated with each is stored in different tables; the schemas of those tables evolve in responses to changes specific to the domain that they manage.
Duplication is far cheaper than the wrong abstraction -- Sandi Metz
This is one of those questions where an answer can become quite long so I'm going to do my best to keep it short. I am no expert in accounting but I have had to implement a lot of it in my career. As such I will be developing one of those generic sub-domains when I have time (one day).
One of my recommendations is not to build classification as a code structure. However, it isn't always easy to identify classification. A "simple" example may be a Customer. We could have a GoldCustomer and SilverCustomer. We could subclass these from an abstract Customer. We have to decide why we are doing this. If, for example, it is to determine that some minimum order amount per period requires and upgrade/downgrade the customer Type in order to qualify for some discount then that can be easily abstracted into its own concept. If the business decides to add PlatinumCustomer or BronzeCustomer then we have to make code changes to inherit from the abstract class. If we rather model that concept as something that can be defined through additional instances (data) then we do not need to have code structures representing those:
public class CustomerDiscount
{
public int Type { get; }
public decimal MinimumSpend { get; }
public int Period { get; }
public decimal DiscountPercent { get; }
}
What I am getting at is that a generic subdomain that may be purchased off-the-shelf (as stated by #p|a|x) would not know about any concepts in any other domain but would need to be able to represent the requirement as a set of instances that relate to its domain specific language.
At the heart of it accounting is about an Account that has debits and credits. From there it is a matter of grouping transactions using a Journal and having some form of PostingRule that could represent the breakdown of amounts into transactions. If memory serves Martin Fowler has some accounting bits in his analysis patterns book. Your accounts are also classified using a Chart of Accounts (COA) and sometimes these are standardised (SCOA). These classifications are what make things interesting in that they typically also determine your posting rules.
I am no fan of abstract classes in your domain as they tend to complicate matters but, as mentioned by #p|a|x, there is no reason to avoid them totally. I find abstract classes and inheritance in general are better suited to technical concerns than business domain models. If you have some technical solution to a business bit then you may find them useful. If you do find yourself considering inheritance of any kind try to see if you cannot represent the relationship using some other concept/class.

The meaning of "entity" in Domain-Driven Design

I attended a Webinar today by someone quite famous and respected author, lecturer, and expert in software engineering, architecture, and design. The webinar topic was "Incremental Architecture". This luminary stated that the concept of an entity in DDD has nothing to do with the concept of entity in databases. It was an unfortunate choice of term by Eric Evans in his original 2003 book. I was not satisfied with his explanation, and I find that his statement to potentially be very confusing to anyone trying to use DDD in design.
My question: what exactly does the term entity in DDD mean? - if it is not the very well understood and very well defined concept of entity in databases, ORM frameworks, JPA, development frameworks (Spring), etc.
Extensive research in software architecture.
This is a question about DDD strategic design. Coding is not involved.
Not relevant to my question. You allow a topic tag about DDD, which is a design approach, not a coding approach, yet you insist on having code-related questions. How is DDD related to coding?
My question: what exactly does the term entity in DDD mean?
Evan's defined entity in Chapter 5 (A Model Expressed in Software) of Domain Driven Design.
Entities (a.k.a. Reference Objects) ... are not fundamentally defined by their properties, but rather by a thread of continuity and identity.
An object defined primarily by its identity is called an ENTITY.
An ENTITY is anything that has continuity through a life cycle and distinctions independent of attributes that are important to the application's user.
It is an in memory abstraction of something that changes over time. It's a temporally varying membership function which for time t maps an identifier to some state. It's used within the domain model to represent things that change.
An example of a entity in a domain model might be... a question on stack overflow.
The meaning of "entity" in Domain-Driven Design
When somebody edits the text, or changes the title, or downvotes... it's still the same question, in that there's a progression from what the text used to be to what the text is now. It changes over time from having this text to having that text.
A simple entity in a domain model might map to a single row in a relational database, but it won't necessarily do so. More precisely, we might save the current state of the entity in a single row. But if that state includes a collection, then it is likely that the state will be distributed across multiple rows, perhaps in multiple tables.
You allow a topic tag about DDD, which is a design approach, not a coding approach, yet you insist on having code-related questions. How is DDD related to coding?
If The Source Code is The Design, then the design necessarily includes coding. The middle section of the Domain Driven Design book, which gets most of the attention, covers topics in modeling domains in code.
Truth be told: domain-driven-design turns up fewer questions with authoritative answers than, for example java.
An entity is a type that has an identity. The id could be anything but it has to be unique to the system and in fact depending on the subdomain you are in, the identity/entity might change.
For example:
A database might have a "User" Table that has fields "firstname", "lastname" e.t.c.
In DDD for an ecommerce application's purchase subdomain, you might have "Shoppers". These Shoppers might have an id of "firstname lastname". In the "Shipping" subdomain of the same application, you'll also have the concept of a "Shopper"(or buyer) but this time the identity of the shopper might be "Full address".
So, where a database entity is nothing more than a grouping of data with an identifier, A DDD entity is a concept. The concept is pertinent to the system, described in the ubiquitous language and is the central actor around which many functions in the domain will operate. The data that populates a DDD's entity usually comes from several datatable entities.

why we need to identify the entity and value object?

In Domain Driven Design,domain objects are fall into two categories,entity and value object.It is very easy to make out which is entity,which is value object,but i don't know why we have to do that?Before the advent of DDD, we model the domain without entity and value object.After the DDD was put forwar,we use entity and value object to classify domain object, so what is the advantage of such classification?
domain objects are fall into two categories,
Actually, no, objects are a possible implementation of a domain Concept , which is basically just information, not code. A concept can be an Entity because it makes sense to identify it in a uniquely and consistent manner, regardless how it changes over time (e.g: a Customer can change their name but it's the same customer. 2 customers with the same name are not necessarily the same person).
A Value Object (a name that still reminds us that DDD started a bit too coupled to OOP) represent a Domain concept that it's just a value. Or more precisely, the business only cares about its value. If you change it, it's another value all together. Basically, 5 dollars is 5 dollars, you don't really care which is which, any of them is good enough, because only the value is important.
Another thing is, as a domain modeler you identify the nature of a concept based on how the business looks at a concept. The business tells you what they care about.
Now, that we know that a concept can be a Entity, we can select a certain instance of it (User with Id 3). You can't do that with VO, because a VO doesn't have an identity.
Even more, when we identify aggregates, most of the time, the aggregate components (other concepts) are mostly VOs, because they usually are just values (but they do respect business constraints).
So, in conclusion, we classify concepts into Entity and VO, because
The business sees them in this manner: uniquely identifiable or just value
Entities keep their identity regardless how they change (obviously the identity itself is read-only), we treat each one as unique
VO are values that can be used interchangeably, we don't care which is which as long as they represent the same value (which itself, as an implementation detail can be a complex - composite - value). Also, a VO by its nature is immutable, so we know that we can't change it without becoming another value.
Before the advent of DDD, we model the domain without entity and value object.After the DDD was put forwar,we use entity and value object to classify domain object, so what is the advantage of such classification?
You should review Chapter 5 ("A Model Expressed in Software") of the Blue Book.
Evans writes:
Defining objects that clearly follow one pattern or the other makes the objects less ambiguous and lays out the path toward specific choices for robust design.
Tracking the identity of ENTITIES is essential, but attaching identity to other objects can hurt system performance, add analytical work, and muddle the model by making all objects look the same.
... bidirectional associations between two VALUE OBJECTS just make no sense. Without identity, it is meaningless to say that an object points back to the same VALUE OBJECT that points to it. The most you could say is that it points to an object that is equal to the one pointing to it, but you would have to enforce that invariant somewhere.
My own summary would be this: recognizing that some domain concepts are entities is useful, because it encourages the designer to acknowledge that identity, continuity, and life cycle are important concerns for the entity in this domain. Similarly, recognizing that a concept is a value immediately frees you from those concerns, bringing your attention to their immutable nature and equivalence.

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.

Resources