UML and Implementation: Associating Classes through IDs - uml

I was recently studying an online course. it was recommended that to reduce coupling we could simply pass the ID from the customer object to the Order object. that way the Order did not have to have a full reference to the Customer class.
The idea certainly seems simple and why pass a whole object if you don't need all its attributes?
1) What do you think of this idea?
2) How would I express the relationship between the Customer class and the Order class in UML if only an ID is passed. This isn't just an example of aggregation is it? Doesn't composition and aggregation require more than just passing a value?
Thanks!

First of all you need to be clear about what UML actually is. On the one hand you have an idea and on the other side there is some code running on hardware. Ideally the latter supports the first in a way that brings added value to a user of the idea. Now, there are many possibilities to describe the way from idea to code. And UML is one of them. It is possible to describe each step on this way but for pragmatic reasons UML stops at the border of code, namely programming languages.
Now for you concrete question: Any object can be seen as an instance. That is some concrete memory partition with a fixed address. Programming languages realize instances by allocating memory and using the start address as reference. And since this reference does not change the object can be identified by its address. Clearly then, an association will just be the a pointer. And an association class will hold two (or more) such pointers.
Honestly, the very first time I started with OO I was also confused and thought that it's a waste of resource to pass those large objects. But since it's just a pointer it's really easy going.
Again, things can get more difficult if you need to persist objects. In that case you need an artificial key you can save along with the object and you will likely need tables to map artificial key to the concrete instance address.

The answer to this question depends on a number of factors, which I started listing in a comment attached to your question. I will assume that you are either using UML to create a Domain Model, or you are describing an implementation done using a statically typed language.
If you are using UML to create a Domain Model, you are obfuscating the semantics when you use an ID to "link" classes. Just draw and annotate the association and you're done.
If you are describing an implementation done using a statically typed language - types exist for a reason. Using generic IDs to link things means that the information that the system needs most become more indirect, and therefore more opaque (which is bad). In your case, the Order object still must acquire a typed reference to a Customer object to do anything with it.
For example, the Order may acquire a reference to the Customer by invoking a lookup by the ID, but it must cast the reference to an appropriate type to invoke anything on the Customer object. So you haven't reduced the coupling from the Order to the Customer. You just buried it somwhere else.

Related

DDD: Domain Objects Structure

I'm new to DDD and I want to clearly understand each domain object structure and role:
Aggregate Root:
1.1. The only contact point the client can interact with the domain objects, the client should not be able to modify or create new Entities or value objects whiteout the aggregate root? (Yes/No)
1.2. Can an aggregate root contain only value objects ? for example User root, it contain only address, phone, things which are value objects as far as I understand. So is it a sign of bad design when your aggregate root contain only value objects? shall it contain only entities and via entities interact with value objects?
Entities: Shall the entities contain only value objects? or it can also contain other entities? can you give me a simple example please ?
Value Objects: shall I go ahead and encapsulate every primitive type in an value object? I can go deep and make every primitive type as an value object, for example: PhoneNumber can be a string or an value object which contains country code, number. the same thing can be applied to all other primitive type value such as name, email. So where to draw the line ? where to say "Ok I'm going to deep", or going deep is the right way of doing DDD?
Factories: Do I really need them? I can go ahead and write an static method within the domain object which knows more precisely how to construct it, am I doing wrong ?
Sorry for the long questions, but I'm feeling little lost despite of continues reading, if you can help me I would be glad.
I'll try to answer all your questions:
1.1. The only contact point the client can interact with the domain objects, the client should not be able to modify or create new Entities or value objects whiteout the aggregate root? (Yes/No)
Entities live within ARs and allowing the client to create them would violate encapsulation, so for entities you are correct, ARs create their own entities which don't get exposed to the outside (copies/immutable views could be).
On the other hand, value objects are generally immutable and therefore there's no harm in having them supplied to the AR as data inputs.
In general all modifications needs to go through the AR so that the AR is aware of the modification. In special situations the AR could detect modifications within it's cluster by listening to events raised by internal entities when it's impractical to go through the root.
1.2. Can an aggregate root contain only value objects ? for example User root, it contain only address, phone, things which are value objects as far as I understand. So is it a sign of bad design when your aggregate root contain only value objects? shall it contain only entities and via entities interact with value objects?
Favor value objects as much as you can. It's not unusual for all parts of an AR being modeled as values. However, there's no limitation or law stating whether or not an AR should have only values or entities, use the composition that's fit to your use case.
Entities: Shall the entities contain only value objects? or it can also contain other entities? can you give me a simple example please ?
Same answer as above, no limitation nor law.
Value Objects: shall I go ahead and encapsulate every primitive type in an value object? I can go deep and make every primitive type as an value object, for example: PhoneNumber can be a string or an value object which contains country code, number. the same thing can be applied to all other primitive type value such as name, email. So where to draw the line ? where to say "Ok I'm going to deep", or going deep is the right way of doing DDD?
Primitive obsession is worst than value object obsession in my experience. The cost of wrapping a value is quite low in general, so when in doubt I'd model an explicit type. This could save you a lot of refactoring down the road.
Factories: Do I really need them? I can go ahead and write an static method within the domain object which knows more precisely how to construct it, am I doing wrong ?
Static factory methods on ARs are quite common as a mean to be more expressive and follow the UL more closely. For instance, I just modeled as use case today where we had to "start a group audit". Implemented a GroupAudit.start static factory method.
Factory methods on ARs for other ARs are also quite common, such as var post = forum.post(author, content) for instance, where Post is a seperate AR than Forum.
When the process requires some complex collaborators then you may consider a standalone factory though since you may not want clients to know how to provide and setup those collaborators.
I'm new to DDD and I want to clearly understand each domain object structure and role
Your best starting point is "the blue book" (Evans, 2003).
For this question, the two important chapters to review are chapter 5 ("A model expressed in software") and chapter 6 ("the life cycle of a domain object").
ENTITIES and VALUE OBJECTS are two patterns described in chapter 5, which is to say that they are patterns that commonly arise when we are modeling a domain. The TL;DR version: ENTITIES are used to represent relationships in the domain that change over time. VALUE OBJECTS are domain specific data structures.
AGGREGATES and FACTORIES are patterns described in chapter 6, which is to say that they are patterns that commonly arise when we are trying to manage the life cycle of the domain object. It's common that modifications to domain entities may be distributed across multiple sessions, so we need to think about how we store information in the past and reload that information in the future.
The only contact point the client can interact with the domain objects, the client should not be able to modify or create new Entities or value objects whiteout the aggregate root?
Gray area. "Creation patterns are weird." The theory is that you always copy information into the domain model via an aggregate root. But when the aggregate root you need doesn't exist yet, then what? There are a number of different patterns that people use here to create the new root entity from nothing.
That said - we don't expect the application to be directly coupled to the internal design of the aggregate. This is standard "best practice" OO, with the application code coupled to the model's interface without being coupled to the model's implementation/data structure.
Can an aggregate root contain only value objects ?
The definition of the root entity in the aggregate may include references to other entities in the same aggregate. Evans explicitly refers to "entities other than the root"; in order to share information with an entity other than the root, there must be some way to traverse references from the root to these non-root entities.
Shall the entities contain only value objects?
The definition of an entity may include references to other entities (including the root entity) in the same aggregate.
shall I go ahead and encapsulate every primitive type in an value object?
"It depends" - in a language like java, value objects are an affordance that make it easy for the compiler to give you early feed back about certain kinds of mistakes.
This is especially true if you have validation concerns. We'd like to validate (or parse) information once, rather than repeating the same check every where (duplication), and having validated vs unvalidated data be detectably different reduces the risk that unvalidated data leaks into code paths where it is not handled correctly.
Having a value object also reduces the number of places that need to change if you decide the underlying data structure needs improvement, and the value object gives you an easily guessed place to put functions/methods relating to that value.
Factories: Do I really need them?
Yes, and...
I can go ahead and write an static method within the domain object
... that's fine. Basic idea: if creating a domain object from so sufficient set of information is complicated, we want that complexity in one place, which can be invoked where we need it. That doesn't necessarily mean we need a NOUN. A function is fine.
And, of course, if your domain objects are not complicated, then "just" use the objects constructor/initializer.

Should DDD entities compare by reference or by ID?

When I started using DDD, I created Equals() methods in my entities that compared the ID of the entity. So two entity objects with the same ID would be considered equal.
At some point I thought about that and found that two entities in different states should not be considered equal, even when they describe the same thing (i.e. have the same ID). So now I use reference equality for my entities.
I then stumbled over this answer by Mark Seemann, where he writes
Entities are equal if their IDs equal each other.
Now, of course, I'd like to know which approach is better.
Edit: Note that the question is not whether having two instances of the same entity at the same time is a good idea. I'm aware that in most situations it is probably not.
The question is twofold. First, what you really want to know is
How to handle terms that the X language (or Y framework) impose when I code a domain model with it?
C# for example imposes you that any new concept you define inherit a certain set of public methods. Java includes even more methods.
I've never heard a domain expert talking about hash codes or instance equality, but this is one of those situations when the (often misunderstood) quote "don't fight the framework" from Evans apply: just teach developers to not use them when they do not belong to domain's interfaces.
Then, what you want to know is
What is an entity? How it relates to its own identity?
Start with why! You know that entities are terms of the ubiquitous language that are identifiable.
But WHY?
Plain simple: entities describe concepts whose evolution in time is relevant in the context of the problem we are solving!
It is the relevance of the evolution that defines the entity, not the other way around! The identity is just a communication tool to keep track of the evolution, to talk about it.
As an example think about you: you are a person with a name; we use your name to communicate about your interactions with the rest of the world during your life; still, you are not that name.
Ask yourself: why I need to compare domain entities? Is the domain expert talking this way? Or I'm just using a DDD parlance to describe a CRUD application that interact with a relational database?
To me, the need to actually implement Equals(object) or GetHashCode() into an entity looks like a smell of an inadequate infrastructure.
Entities shouldn't be compared like that, in the first place. There is no valid use case (outside testing, but then again the assertion library should handle this for you) to see if 2 entities are equal using the object's Equals method.
What makes an Entity unique is its Id. The purpose of the id is to say 'this very entity is different from other entities despite having identical properties/values'.
That being said, in a Domain you might need to compare a concept instance with another instance. The comparison is done according to Bounded Context (or even Aggregate) specific Domain rules. It doesn't matter an entity is involved, it could have been a value object as well.
Basically the 'comparison' should be a Domain use case which will be probably implemented as a service. This has no relation to an object's Equals method, which is a technical aspect.
When doing DDD, don't think like a programmer (i.e technical aspects) think like an architect (high level). Code, programming language etc is just an implementation detail.
I think it's bad idea to have the two separate instances of the same entity in different states. I can't think of a scenario where that would be desirable. Maybe there is one? I believe there should only ever be one instance of a given entity with a particular ID.
In general I'd compare their equality using their IDs.
But if you wanted to check if they are the same object reference then you could just use:
if (Object.ReferenceEquals(entityA, entityB))
{
DoSomething();
}

Value Objects in CQRS - where to use

Let's say we have CQRS-inspired architecture, with components such as Commands, Domain Model, Domain Events, Read Model DTOs.
Of course, we can use Value Objects in our Domain Model. My question is, should they also be used in:
Commands
Events
DTOs
I haven't seen any examples where Value Objects (VO) are used in the components mentioned above. Instead, primitive types are used. Maybe it's just the simplistic examples. After all, my understanding of VOs use in DDD is that they act as a glue for the whole application.
My motivation:
Commands.
Let's say user submits a form which contains address fields. We have Address Value Object to represent this concept. When constructing command in the client, we should validate user input anyway, and when it is well-formed, we can create Address object right there and initialize Command with it. I see no need to delegate creation of Address object to command handler.
Domain Events.
Domain Model already operates in terms of Value Objects, so by publishing events with VOs instead of converting them to primitive types, we can avoid some mapping code. I'm pretty sure it's alright to use VOs in this case.
DTOs.
If our query-side DTOs can contain Value Objects, this allows for some more flexibility. E.g., if we have Money object, we can choose whether to display it in EUR or USD, no need to change Read Model.
Ok I've changed my mind. I have been trying to deal with VOs a bunch lately and after watching this http://www.infoq.com/presentations/Value-Objects-Dan-Bergh-Johnsson it clarified a couple of things for me.
Commands and Event are messages (and not objects, objects are data + behavior), in some respects much like DTOs, they communicate data about an event and they themselves encapsulate no behavior.
Value Objects are not like DTOs at all. They are a domain representation and they are, generally speaking, rich on behavior like all other domain representations.
Commands and Events communicate information into and out of the domain respectively, but they themselves do not encapsulate any behavior. From that perspective it seems wrong and a possibly a violation context boundaries to pass VOs inside of them.
To paraphrase Oren (though he was referring to nHibernate and WCF) "Don't send your domain across the wire".
http://ayende.com/Blog/archive/2009/05/14/the-stripper-pattern.aspx
If you want to communicate a value object, then I suggest passing the necessary attributes needed to re-construct the VO within them instead.
Original Text (for posterity):
If you are asking if Value Objects can be passed by the domain model to events or passed in by commands, I don't really see a huge problem with the former, though the latter may violate some of the rules of the aggregate root being the "owner" of values.
That said a value object represents concepts like for example a color. You don't have green, you are green or not. There seems to be nothing intrinsically wrong with a command telling you that you are green by passing this.
Reading the chapter from DDD on the Aggregate Root pattern explains Entities and Value Objects quite well and is worth reading over a few times.
I say it's a bad idea.
There's a reason we don't do the same with entities - to avoid coupling other parts of the system to the domain (in the wrong places). The same is true for Value Objects, the only difference between value objects and entities is lifetime and ownership - these differences do not affect how we should and should not couple to them.
Imagine that you make an event contain a VO. A change in your domain requires you to change that VO. You've now boxed yourself into a corner where your event is also forced to change, ditto for any Commands or DTO's it's a part of.
This is to be avoided.
Use DTO's and/or primitives. Map them (AutoMapper makes it a 1-line deal).
Similar to other answers, in SOA this would break encapsulation of the service as the domain is now leaking out.
According to Clean Code your DTOs are data structures (just to add another term), while value objects are objects. The difference that objects can have behavior. Mixing data structures with objects is generally a very bad idea, because it will be hard to maintain the hybrid you get.
I don't feel right to put value objects to DTOs from an architecture perspective as well. The value objects are inside of the domain model while the DTOs you mentioned are defining the interface of the model. We usually build an interface to decouple the outside world from the inside of something. So in the current case we added DTOs to decouple the outside world from the value objects (and other model related stuff). After that adding value objects to the interface is crazy.
So you haven't met this solution yet because it is an anti-pattern.
Value Objects are or at least should be immutable. Once instantiated with a value that value will never change throughout the lifetime of the object. Thus, passing VOs as data to DTOs (such as Events) should not be an issue since all you can do with them is get their value. At the most their value in a differing representation such as toString() as opposed to an original getValue() which might return an integer or whatever the value is.

Mutable Value Objects / Sharing State (and beer brewing!)

I'm a rusty programmer attempting to become learned in the field again. I've discovered, fitfully, that my self-taught and formal education both induced some bad habits. As such, I'm trying to get my mind around good design patterns, and -- by extension -- when they're wrong. The language is Java, and here's my issue:
I'm attempting to write software to assist in beer brewing. In brewing, sometimes you must substitute a particular variety of hop for what's called for in the recipe. For example, you might have a recipe that calls for 'Amarillo' hops, but all you can get is 'Cascade', which has a similar enough aroma for substitution; hops have an Alpha Acid amount (per a given mass), and the ratio between two hops is part of the substitution formula. I'm attempting to model this (properly) in my program.
My initial go is to have two objects. One a HopVariety, which has general descriptive information about a variety of hop, and one a HopIngredient, which is a particular instantiation of a HopVariety and also includes the amount used in a given recipe. HopIngredient should have knowledge of its variety, and HopVariety should have knowledge of what can be used as a substitute for it (not all substitutions are symmetric). This seems like good OOP.
The problem is this: I'm trying to follow good practice and make my value objects immutable. (In my head, I'm classifying HopVariety and HopIngredient as value objects, not 'actors'.) However, I need the user to be able to update a given HopVariety with new viable substitutions. If I follow immutability, these changes will not propagate to individual ingredients. If choose mutability, I'm Behaving Badly by potentially introducing side-effects by sharing a mutable value object.
So, option B: introduce a VarietyCollection of sorts, and loosely couple the ingredients and the varieties by way of a name or unique identifier. And then a VarietySubstitutionManager, so that varieties don't hold references to other varieties, only to their ids. This goes against what I want to do, because holding a reference to the variety object makes intuitive sense, and now I'm introducing what feels like excessive levels of abstraction, and also separating functions from the data.
So, how do I properly share state amongst what amounts to specific instances? What's the proper, or at least, sanest way to solve the problem?
Are you sure HopVariety should be a value object? It sounds to me like an entity - "Amarillo" hop variety is one and only one, so it should be a uniquely identifiable object. Just like "Tony Wooster" is only one (well not exactly, but you get the point ;) )
I recommend reading about Domain Driven Design and the differences between entities and value objects.
BTW: DDD book has a lot of examples of situations like yours and how to handle them.
I think your choices are either to
have the 'update variety' function walk the existing object graph and create a new one with all of the ingredients updated, or
keep using mutability
With the information at hand, it isn't clear to me which is better for your situation.
How badly do you want to avoid mutation of objects with multiple references?
If you want the recipe collection to reflect the user updates to the variety set, and you want to avoid mutable fields in your objects, then you'll be forcing yourself into using functional object update to handle user input.
At the end of that road lies the I/O monad. How far do you want to go in that direction?
With a functional language that allows mutation side-effects, e.g. S/ML etc., you might opt to keep your variety and ingredient objects pure, and to store functions that return the current variety object from the latest variety collection stored in a single mutable reference cell. This might seem like a reasonable way to split the difference.

In DDD, what are the actual advantages of value objects?

I have gotten so far that I understand entity objects have an ID while value object have not, but in the most common example you have the person entity that have a address value object attached to it. What is the big advantage of creating a separate address object instead of just keeping the address properties within the Person Entity?
In addition to the things already mentioned, Greg Young makes a big deal out of the fact that since they are immutable, you can validate them on creation and never worry about validation again. If the state cannot be changed, then you know it's always valid.
Value objects can be used as arguments for other methods in other classes
It can make your design clearer
It might help with performance optimization (example: fly-weight pattern)
Value objects can be reused in different entities. (example: user and location entities with address value objects.
Don't forget that "not having an id" is not the only difference between value objects and entities, being immutable is also very important.
Think of it as a reusable component. You can make it into a home address, work address without much extra effort. You can use it to decouple other systems from the person entity. Say you introduce a business entity. It will also have an adress.
Related to this subject is another important subject: composition vs. inheritance

Resources