Always valid domain model entails prefixing a bunch of Value Objects. Doesn't that break the ubiquitous language? - domain-driven-design

The principle of always valid domain model dictates that value object and entities should be self validating to never be in an invalid state.
This requires creating some kind of wrapper, sometimes, for primitive values. However it seem to me that this might break the ubiquitous language.
For instance say I have 2 entities: Hotel and House. Each of those entities has images associated with it which respect the following rules:
Hotels must have at least 5 images and no more than 20
Houses must have at least 1 image and no more than 10
This to me entails the following classes
class House {
HouseImages images;
// ...
}
class Hotel {
HotelImages images;
}
class HouseImages {
final List<Image> images;
HouseImages(this.images) : assert(images.length >= 1),
assert(images.length <= 10);
}
class HotelImages {
final List<Image> images;
HotelImages(this.images) : assert(images.length >= 5),
assert(images.length <= 20);
}
Doesn't that break the ubiquitous languages a bit ? It just feels a bit off to have all those classes that are essentially prefixed (HotelName vs HouseName, HotelImages vs HouseImages, and so on). In other words, my value object folder that once consisted of x, y, z, where x, y and z where also documented in a lexicon document, now has house_x, hotel_x, house_y, hotel_y, house_z, hotel_z and it doesn't look quite as english as it was when it was x, y, z.
Is this common or is there something I misunderstood here maybe ? I do like the assurance it gives though, and it actually caught some bugs too.

There is some reasoning you can apply that usually helps me when deciding to introduce a value object or not. There are two very good blog articles concerning this topic I would like to recommend:
https://enterprisecraftsmanship.com/posts/value-objects-when-to-create-one/
https://enterprisecraftsmanship.com/posts/collections-primitive-obsession/
I would like to address your concrete example based on the heuristics taken from the mentioned article:
Are there more than one primitive values that encapsulate a concept, i.e. things that always belong together?
For instance, a Coordinate value object would contain Latitude and Longitude, it would not make sense to have different places of your application knowing that these need to be instantiated and validated together as a whole. A Money value object with an amount and a currency identifier would be another example. On the other hand I would usually not have a separate value object for the amount field as the Money object would already take care of making sure it is a reasonable value (e.g. positive value).
Is there complexity and logic (like validation) that is worth being hidden behind a value object?
For instance, your HotelImages value object that defines a specific collection type caught my attention. If HotelImages would not be used in different spots and the logic is rather simple as in your sample I would not mind adding such a collection type but rather do the validation inside the Hotel entity. Otherwise you would blow up your application with custom value objects for basically everything.
On the other hand, if there was some concept like an image collection which has its meaning in the business domain and a set of business rules and if that type is used in different places, for instance, having a ImageCollection value object that is used by both Hotel and House it could make sense to have such a value object.
I would apply the same thinking concerning your question for HouseName and HotelName. If these have no special meaning and complexity outside of the Hotel and House entity but are just seen as some simple properties of those entities in my opinion having value objects for these would be an overkill. Having something like BuildingName with a set of rules what this name has to follow or if it even is consisting of several primitive values then it would make sense again to use a value object.
This relates to the third point:
Is there actual behaviour duplication that could be avoided with a value object?
Coming from the last point thinking of actual duplication (not code duplication but behaviour duplication) that can be avoided with extracting things into a custom value object can also make sense. But in this case you always have to be careful not to fall into the trap of incidental duplication, see also [here].1
Does your overall project complexity justify the additional work?
This needs to be answered from your side of course but I think it's good to always consider if the benefits outweigh the costs. If you have a simple CRUD like application that is not expected to change a lot and will not be long lived all the mentioned heuristics also have to be used with the project complexity in mind.

Related

How to access variables from another class using getter

I am a beginner programmer and I am having a hard time grasping getters and setters. I just do not see the point.
I am trying to access the variable in Class A and use that value in class B to do some function. I thought I could use getter to access that value but that returns null since I understand that I am creating a new object with new values now. Then what is the point of a getter then?
I passed the variables over using the method parameters but that seems counter intuitive to my beginner's mind. I just don't understand that entire concept. Or am I wrong. I can use getters to access the value of another class's variable without making it static?
If I'm understanding you correctly, what you're asking is "Why do I need instance variables, with getter and setter methods to read/modify those variables, when I can just pass data into an object using method arguments?" Does that sound about right?
The answer gets to the heart of what OOP (object-oriented programming) is all about. The central concept of OOP is that you create distinct objects to represent discrete pieces of data. For example, you might want to track names and ages for some group of people; in that case, you would use different objects to represent (and by extension, store and manage data about) each individual person.
Person 1 ("Bill", 52)
Person 2 ("Mary", 13)
Person 3 ("Lana", 29)
The purpose of the class in this model is simply to define the specifications of these objects (e.g. a "Person" consists of a name and an age).
Why is this useful? First, this is a pretty intuitive system, since you can think of the objects you're creating as being actual real-life objects. Second, it makes it easy to work with data that are related. If, for example, we wanted to concatenate (join together in a string) a person's name with their age, having an object representing each person makes that easy! Just look at each object, one by one, and use getters to access the values for each instance.
To do this in a non-OOP way, we would need some other way to store the information -- perhaps as a list of names and a separate list of ages.
List of names: ["Bill", "Mary", "Lana"]
List of ages: [52, 13, 29]
In that kind of setup, it's not as easy to see which name relates to which age -- the only thing they have connecting them is their position within the list. And if the lists were sorted, those positions could change!
So, in short: object instances are a great way to handle many similar discrete collections of data.
As far as why we generally use getter methods and setter methods when working with those instances, instead of just exposing properties directly, a great explanation can be found here. But it bears mentioning that different languages handle this differently. In JavaScript, for example, all properties are accessible directly. In Ruby, none of them are, and you must use setters and getters to see/modify object instance variables.
I hope this provides some clarity!

Difference between child entity and value object in DDD

I've found this great article where in the section on aggregates' structure, I can see a distinction being made between child entity (here: order item) and value object (here: address).
I'm not entirely sure how they differ on an architectural level. I'd like to say that both of them are value objects (aggregated within the root Order).
What am I missing in the picture?
Value Objects are much "values with methods" than they are "objects".
"Address" as a value, isn't fundamentally different from a primitive like integer. The significant difference between the two is that most generic programming languages don't come with a built in address type. So we have to roll our own -- or re-use one from a library.
In many modern languages, you can only roll your own by using the "object" idioms to create your customized data structure and the query semantics that you want.
Value objects are data with query semantics attached.
Entities, on the other hand, change over time. A way of thinking of an entity's implementation is that, under the covers, the entity is a mutable reference to a value.
void Entity::onChange(data) {
// dereference to get the current state value
val oldState = this.state;
// use a pure function to compute a new state value
val newState = stateChange(oldState, data);
// update the reference
this.state = newState;
}
The specific data structure being used to hold the state is an implementation detail of the entity of no interest to other elements in the solution.
A child entity is an entity, which is to say that it is an object with the responsibility for managing some implicit data structure. It is designed for change.
It's "just like the root", but on a smaller scale -- the root has a more complete sense of the entire context.
See also
Classes vs Data Structures -- Robert Martin
Perception and Action -- Stuart Halloway

Should equals() method of value objects strive to return true by using transformations of attributes?

Assume we have a value object Duration (with attributes numberOfUnits, unit). Would it be a good idea to treat these objects as equal (for example, overriding Object.equals()) if they have the same duration but different units? Should 1 min be equal to 60 sec.
There are many contradicting examples. With java's BigDecimal compareTo() == 0 does not imply equals() == true (new BigDecimal("0").equals(new BigDecimal("0.0")) returns false). But Duration.ofHours(24).equals(Duration.ofDays(1)) returns true.
That's an unfortunately complicated question.
The simple answer is no: the important goal of value objects is to correctly model queries in your domain.
If it happens that equals in your domain has nice properties, then you should model them and everything is awesome. But if you are modeling something weird then getting it right trumps following the rules everywhere else.
Complications appear when your implementation language introduces contracts for equals that don't match the meaning in your domain. Likely, you will need to invent a different spelling for the domain meaning.
In Java, there are a number of examples where equals doesn't work as you would expect, because the hashCode contract prohibits it.
Well... I upvoted #jonrsharpe comment because without knowing the context it is almost impossible to give you an answer.
An example of what #jonrsharpe means could be that if in your domain you are using Duration VO to compare users input (who choose numberOfUnits and unit in a UI) it is obvious that Duration in minutes is not equal to Duration in seconds even if 1 min = 60 sec because you want to know if the users inputs the same things, and in this case they not.
Now, assuming that you will use Duration just for other things in which the format does not matter and ever means the same thing for domain rules (i.e. outdate something):
Why do you need Duration.unit attribute if it gives you nothing of value in your domain?
Why can not you just work with one unit type internally?
If it is just because different inputs/outputs in your system you should transform it to your internal/external(UI, REST API, etc) representation before apply rules, persist the VO (if needed) and/or showing it in a UI. So, separate input/output concerns from your domain. Maybe Duration (with unit attribue) is not a VO is just part of your ViewModel.

To Have An ID or Not To Have An ID - Regarding Value Object

Let's say two domain objects: Product and ProductVariety (with data such as color, size etc). The relationship between these two is one-to-many. Conceptually saying in the domain driven design, the ProductVariaty should be a value object, which is not the same object once its data is changed. From the implementation point of view, however, it is better to have some sort identification for the ProductVariaty so that we know which ProductVariety is selected and so on. Is an only solution to convert it to an entity class?
The following is a code segment to illustrate this situation.
#Embeddable
class ProductVariety {...}
#Entity
class Product {
#ElementCollection
private Set<ProductVariety> varities;
...
}
Conceptually saying in the domain driven design, the ProductVariaty should be a value object, which is not the same object once its data is changed
That's not quite the right spelling. In almost all cases (many nines), Value Object should be immutable; its data never changes.
Is an only solution to convert it to an entity class?
"It depends".
There's nothing conceptually wrong with having an identifier be part of the immutable state of the object. For example, PANTONE 5395 C is an Identifier (value type) that is unique to a particular Color (value type).
However, for an identifier like PANTONE 5395 C to have value, it needs to be semantically stable. Changing the mapping of the identifier to the actual color spectrum elements destroys the meaning of previous messages about color. If the identifier is "wrong", then the proper thing to do is deprecate the identifier and nominate a replacement.
Put simply, you can't repaint the house by taking the label off the old paint can and putting it on a new one.
In that case, there's no great advantage to using the identifier vs the entire value object. But its not wrong to do so, either.
On the other hand, if you are really modeling a mapping, and you want to follow changes that happen over time -- that's pretty much the definition of an entity right there.
What it really depends on is "cost to the business". What are the trade offs involved, within the context of the problem you are trying to solve?
Note: if you really do find yourself in circumstances where you are considering something like this, be sure to document your cost benefit analysis, so that the next developer that comes along has a trail of breadcrumbs to work from.

Domain Driven Design; Can ValueObject contains invariants or specifications?

I'm starting to play with Domain Driven Design and have a question about ValueObjects :
Can they contains invariants or other specifications ?
Consider an immutable ValueObject :
ValueObject (
prop integer: Int
prop string: String
// Value and copy constructor
// Observers for integer and string
// Equality methods on integer and string value
)
Can I add some invariants such that integer > 0 & < 42. Or do they have to be simple transfer without any logic ?
I hope they can but need a confirmation.
A value object (VO) encapsulates a value and its business requirements . This is its purpose: to model a business concept (with its constraints) which happens to be a simple (not always single) value.
A VO is not a Data transfer object (DTO) precisely because it defines a business concept that is valid only in the containing bounded context, while a DTO is meant to cross boundaries.
Value objects should handle the invariants for the data that they encapsulate, or at least as much of it as they can. I tend to do the following, which is actually similar to entities except for the immutable bit:
Constructors should make sure it is created in a valid state
The VO's state is encapsulated, and all changes to it are done through controlled methods/etc
Because value objects are immutable, method changes return a new value object rather than updating the existing state
Having the value objects own their own business logic really helps clean up the code in the entities that use these value objects. This can become a problem with big aggregates\entities, so look for opportunities to pull this behavior out into value objects.
It also makes unit testing lots of edge cases MUCH easier, as you are testing the value object on its own.
Your entity may need to do validation across multiple value objects before decides a change CAN happen, but then the value object is responsible for the change itself.

Resources