Value Objects in a Clean Architecture

2,557 views
Skip to first unread message

Andreas Schaefer

unread,
Jan 10, 2014, 9:39:24 AM1/10/14
to clean-code...@googlegroups.com
In the separate thread "architecture advice" (https://groups.google.com/forum/?hl=en#!topic/clean-code-discussion/qaSR0KgKvkQ) in this group here, one interesting topic came up by mentioning the UserID class from an example in Episode 23 part 1:

value objects

they've got publicity not only through the whole DDD movement. others say they're the "The Heart and Soul of OOP" (http://elephantintheroom.io/blog/2013/10/episode-2-heart-and-soul-of-oop/).

Now I ask myself if in the Clean Architecture they go as a separate thing besides entities (and where to put them in the folder / components structure) or if they are classified as an entity as well but just not having an identity and a lifetime (opposed to "regular" entities in DDD).

What do you think?

Imre Kószó

unread,
Jan 10, 2014, 4:43:54 PM1/10/14
to clean-code...@googlegroups.com
Thanks for the link, Andreas! I've listened to the podcast and found it very interesting. I am just exploring the topic of value objects myself and what I learned so far was very valuable and I am trying to make more and more use of them. I would love to see a detailed guide on their usage and proper implementation though.

Bennie Copeland

unread,
Jan 16, 2014, 1:14:28 PM1/16/14
to clean-code...@googlegroups.com
I've found the book Implementing Domain Driven Design to be very.... valuable... in understanding DDD. The value classes are part of the domain model and lives along side your entity classes. What Uncle Bob calls entities on his Clean Architecture diagram is what DDD calls the domain model. The model consists of values, entities, aggregates, domain services, repository interfaces, etc.
 
@Imre
In the book I referenced above it says:
 
"When you are trying to decide whether a concept is a Value, you should determine whether it possesses most of these characteristics:
  • It measures, quantifies, or describes a thing in the domain (money, address, identity)
  • It can be maintained as immutable. (never changes after construction)
  • It models a conecptual whole by composing related attributes as an integral unit (an address value composed of city, state, country, stree, etc., money with value amount and currency)
  • It is completely replaceable when the measurement or description changes (switch one address for another)
  • It can be compared with others using Value equality ($1 is $1 whether it is in quarters or dimes)
  • It supplies its collaborators with Side-Effect-Free Behavior"
The book goes into much greater depth and I highly recommend it.

Andreas Schaefer

unread,
Jan 17, 2014, 6:02:15 AM1/17/14
to clean-code...@googlegroups.com
The value classes are part of the domain model and lives along side your entity classes

full ack. Then I'd like to know when the following folder structure is given ...

Imagine a folder structure (a VS project)  that has four top level folders:  Interactors, Entities, Boundaries, Gateways.
This is your application
(from Uncle Bob answering in the separate thread "architecture advice" https://groups.google.com/forum/?hl=en#!topic/clean-code-discussion/qaSR0KgKvkQ)

... where would the value objects go? separate folder "valueObjects" or into the "Entities" folder as well?


What Uncle Bob calls entities on his Clean Architecture diagram is what DDD calls the domain model. The model consists of values, entities, aggregates, domain services, repository interfaces

I'd map these to:
(DDD -> Clean Architecture)
entities -> entities
aggregates / aggregate roots -> a concept applied to entities and valueObjects
domain services -> interactors
repository interfaces -> gateway interfaces

how would you map them?

Bennie Copeland

unread,
Jan 22, 2014, 3:50:28 AM1/22/14
to clean-code...@googlegroups.com
The value objects would go in the entities folder.

Your mapping looks correct except for domain services -> interactors. A domain service is part of the domain model, but doesn't fit well into a single class. A domain service can perform a significant business process, transform a domain object from one composition to another, or calculate a value requiring input from more than one domain object. Validation is a good one. The domain service can validate that an entity is in a valid state. If you were using C++, it would be a free function, but in C# and Java it might be a class with static methods.

In DDD there are Application services that map to the interactors. "The application services are the direct clients of the domain model. These are responsible for task coordination of use case flows, one service method per flow. When using an ACID database, the Application Services also control transactions, ensuring that model state transitions are atomically persisted." - Vaughn Vernon "Implementing Domain Driven Design" Chpt 14.

In my solutions I will create a project for a bounded context in the domain model. I will create a second project that implements the interactor layer and depends on the domain model assembly. I'll have a third project that implements the repository interfaces. And a fourth project that implements the presentation layer, ASP.Net MVC4, console app, desktop app, what have you. The application project will have the folder structure that you reference except for the entities folder because that is in its own project.

Andreas Schaefer

unread,
Jan 22, 2014, 11:24:01 AM1/22/14
to clean-code...@googlegroups.com
Bennie,
thanks for your insights and provided references.


Your mapping looks correct except for domain services -> interactors.

ok, I mixed that one up with application services. 
 
 
... Validation is a good one. The domain service can validate that an entity is in a valid state.

Shouldn't an entity guaranty it's (enterprize wide) invariants so that it is impossible for it to be in an invalid state (regarding the enterprize wide invariants) in the first place?
 

... A domain service is part of the domain model, but doesn't fit well into a single class. A domain service can perform a significant business process, transform a domain object from one composition to another, or calculate a value requiring input from more than one domain object. ...
... In DDD there are Application services that map to the interactors. "The application services are the direct clients of the domain model. These are responsible for task coordination of use case flows, one service method per flow. ...

so in DDD, when an operation does not conceptually belong to any domain object (Entity, Value Object or Aggregate[Root]) these operations can be implemented in domain services.
-> Where would those kinds of operations go in a CleanArchitecture?
Would it be one more entity? Would it be something like the Authorizer used by the LoginInteractor in EP 23? Is the before mentioned Authorizer an entity in the first place? Would it be seen as application specific or as enterprize wide? Was it allowed to share logic/functionality residing outside of entities [if that is necessary in the first place!] enterprize wide? -> I assume not and thus (maybe naively) conclude that in a CleanArchitecture: Every functionality, may it conceptually belong to any existing domain object or not, when wanted to be available enterprize wide must again be in the form of an entity ... ehh, right? But then on the other hand, when the operation/functionality just needs to be used in the application specific context ... what would it be, where would it go? Probably into an Interactor (I guess there the concept intersects with DomainServices and ApplicationServices) .. or is it possible to have application specific entities?? .. I guess not.

annotation: In CleanArchitecture in addition to the entities the Interactors contain (only application specific instead of enterpize wide) (validation) business logic as well.
-> This leads me to further questions.
What if an application specific validation logic that conceptually belongs to a specific entity needs to be executed in several Interactors/UseCases? To what kind of component (outside of any entity) should this piece of functionality be extracted in order to stay DRY and where would it reside in the (folder) structure? I really can't imagine that it would be another Interactor because .. why would you potentially do an unnecessary mapping of data onto InteractorRequestDTOs again? We are behind the application boundary already and the logic that we want to call doesn't need to be called from outside the boundary and in addition it isn't necessarily a separate UseCase(Flow/Story).

This question is more of a general nature: As for entities setters (and getters) for private data fields should be avoided where possible, I assume application specific validation logic for such an entity (that resides in the interactors or in the above mentioned components in question) should be executed before the state-changing behaviour _of_ (or _on_) the entity is initiated?
..... that's another part that's kinda difficult to grasp: How to avoid setters on entity objects .. or let's say: when _application specific behaviour_ should be initiated, how do you implement behaviour affecting entities if it is not allowed to implement it for the (enterprize wide) entity object itself? Can it be done only by having some private field setters on the entity? .. Does the term "application specific _behaviour_" makes any sense then? .. Or can the term only be seen for a level as granular as to the Interactors but not any further (because using setters on the entities then would technically not be behaviour anymore)?

so much for now, I'm interested if some of you already wondered about the same things as I do at the moment.

Bennie Copeland

unread,
Jan 22, 2014, 12:23:35 PM1/22/14
to clean-code...@googlegroups.com

Shouldn't an entity guaranty it's (enterprize wide) invariants so that it is impossible for it to be in an invalid state (regarding the enterprize wide invariants) in the first place?

It depends on the level of validation. An entity may be able to validate itself as being correct, but a combination of entities together may represent an invalid state.
  
so in DDD, when an operation does not conceptually belong to any domain object (Entity, Value Object or Aggregate[Root]) these operations can be implemented in domain services.
Correct :)
 
-> Where would those kinds of operations go in a CleanArchitecture?
Would it be one more entity? Would it be something like the Authorizer used by the LoginInteractor in EP 23? Is the before mentioned Authorizer an entity in the first place? Would it be seen as application specific or as enterprize wide? Was it allowed to share logic/functionality residing outside of entities [if that is necessary in the first place!] enterprize wide? -> I assume not and thus (maybe naively) conclude that in a CleanArchitecture: Every functionality, may it conceptually belong to any existing domain object or not, when wanted to be available enterprize wide must again be in the form of an entity ... ehh, right? But then on the other hand, when the operation/functionality just needs to be used in the application specific context ... what would it be, where would it go? Probably into an Interactor (I guess there the concept intersects with DomainServices and ApplicationServices) .. or is it possible to have application specific entities?? .. I guess not.

I think this is a confusion of terms. In the folder structure above there was an Entities folder. My observation is that Uncle Bob has grouped all of the domain model into that one Entity folder. I think it is just a high level grouping to separate out the domain classes from the use case classes. The classes under that Entities folder, in DDD terms are broken down into entities, value objects, aggregates, domain services, etc. In clean architecture parlance, you could just call it another entity. In DDD parlance you would call it a domain service in the model. In truth, everything is a class. Its just how you mentally organize those classes into concepts that I think you are getting hung up on. You could call them all entities if you want or break them up into their DDD concepts, but they would all be under that Entities folder (or in my personal preference an Entities/Domain Model project separate from the use cases.)

If the logic of the service is applicable domain wide and doesn't change regardless of which application requires it, then it would go into the domain model (entity folder). If the logic changes based on the specific application written to use it, then it would be an application service/use case/interactor (whichever term you prefer to use). An example might be sub departments under an organization. In the domain model, it might not care if you add two departments with the same name. But the particular application that is getting written might have a use case that says no two departments can have the same name. That constraint would be implemented as a business rule in the interactor when a new department is being created or renamed. That is business logic, not domain logic, and thus resides in the application layer.

annotation: In CleanArchitecture in addition to the entities the Interactors contain (only application specific instead of enterpize wide) (validation) business logic as well.
-> This leads me to further questions.
What if an application specific validation logic that conceptually belongs to a specific entity needs to be executed in several Interactors/UseCases? To what kind of component (outside of any entity) should this piece of functionality be extracted in order to stay DRY and where would it reside in the (folder) structure? I really can't imagine that it would be another Interactor because .. why would you potentially do an unnecessary mapping of data onto InteractorRequestDTOs again? We are behind the application boundary already and the logic that we want to call doesn't need to be called from outside the boundary and in addition it isn't necessarily a separate UseCase(Flow/Story).

Don't think that you are limited to the folder structure above. Every application is different and has different requirements. In this case, I might create a services folder (either at the root, or under the interactors folder)  and put the validation logic there. But this could also be looked at as another use case itself. And I don't see why a use case can't call another use case.
 
This question is more of a general nature: As for entities setters (and getters) for private data fields should be avoided where possible, I assume application specific validation logic for such an entity (that resides in the interactors or in the above mentioned components in question) should be executed before the state-changing behaviour _of_ (or _on_) the entity is initiated?
..... that's another part that's kinda difficult to grasp: How to avoid setters on entity objects .. or let's say: when _application specific behaviour_ should be initiated, how do you implement behaviour affecting entities if it is not allowed to implement it for the (enterprize wide) entity object itself? Can it be done only by having some private field setters on the entity? .. Does the term "application specific _behaviour_" makes any sense then? .. Or can the term only be seen for a level as granular as to the Interactors but not any further (because using setters on the entities then would technically not be behaviour anymore)?

I'm not entirely sure I'm following the question. The entities can be viewed as being only as restrictive as the domain requires. It should allow the maximum flexibility inherent to the domain. The application layer cannot make the domain more flexible than it already is, but it can make it more restrictive to address the use cases. If the entities need to be more flexible than they already are, then the models are now flawed in light of the new information and understanding, and need to be updated. This shouldn't be viewed as a bad thing as now you have increased your knowledge and understanding of the domain. The application specific validation logic should happen before modifying the entity. There may be side effects to modifying the entity like event triggering. When the entity is modified, It can fire an event off that other entities may be registered to be notified which in turn causes them to modify some state. That would be a real mess to try and undo. :) As for setters, I prefer using setters whether the fields are private or not. Its the perfect place to put validation logic.

Andreas Schaefer

unread,
Jan 22, 2014, 4:33:52 PM1/22/14
to clean-code...@googlegroups.com
thanks so much for your detailed explanations. That all seems to make sense, especially ...

That is business logic, not domain logic, and thus resides in the application layer.
Alternatively you could say that enterprize wide business logic inherently is domain logic. But imho the term 'domain logic' actually makes it much more obvious and understandable. It applies to the concept of the entities. And there it makes sense again that domain = entities :) An entity in domain 1 is conceptually for the most time something different compared to domain 2. the term enterprize just makes it harder to grasp ;)

and
The entities can be viewed as being only as restrictive as the domain requires. It should allow the maximum flexibility inherent to the domain. The application layer cannot make the domain more flexible than it already is, but it can make it more restrictive to address the use cases
very well said!

I need some more time to read and think it through again in some more detial :)

Andreas Schaefer

unread,
Jan 23, 2014, 7:56:39 AM1/23/14
to clean-code...@googlegroups.com
If for application specific businessLogic (not Domain/Model logic) or functionality raises the need to be shared across several applications, then it seems a logical conclusion that these parts can't just be shoved into entities because they're not a domain/model concept. How would you do this and still stay DRY, still use just one codebase?
What comes to mind is extract that functionality out of the interactors (if that's not already the case) and share/use that exact same code base among the several application projects (e.g. "Add as link" in VisualStudio projects). 
But then there'd be the danger that this situation gets hidden by implicitness. One couldn't explicitly notice that this would be one common code base and maybe would change the behaviour of another application my accident.
What about the option to extract to whole separate components and share these? Of course you had to make sure that they'd over the course of time still only contain shared functionality!

Apart from that .. how would this fit CleanArchitecture? I can't see a concept for this requirement at the moment.

Any other ideas?

Bennie Copeland

unread,
Jan 24, 2014, 3:34:30 PM1/24/14
to clean-code...@googlegroups.com
That looks like it is more of a policy issue than anything you could really fix with code. Break the code out into its own project and save it in your source code repository. You would have to have processes to ensure that when the code in this module is modified, that all the other dependent projects are tested to make sure they still work. This would be a great place for a continuous integration server and suites of tests. Then you can change the code with the assurance that your tests should catch any regressions.

Andreas Grimm

unread,
Jan 24, 2014, 5:17:37 PM1/24/14
to clean-code...@googlegroups.com
On Friday, January 24, 2014 9:34:30 PM UTC+1, Bennie Copeland wrote:
... Break the code out into its own project ...

That's what I meant with saying "What about the option to extract to whole separate components and share these?" .. by component I meant project / dll.


... and save it in your source code repository

I'd then tend to use a separate repo for these "not domain but application meta" projects (plural because maybe they'd get further split up by UseCase family). As you said .. a good CI server (configuration) can then automatically keep track of the repo dependencies, on pushes being made will trigger all the necessary builds and run the related test suites.
 

That looks like it is more of a policy issue than anything you could really fix with code.

Along the lines of my previous question "how would this fit CleanArchitecture? I can't see a concept for this requirement at the moment."  .. what bugs me here is that up to now regarding CleanArchitecture no such a statement was "officially" made that would allow it to share between applications other than by flexing entities.  .. but I guess I'm hung up on this again because your explanation of how entities/model/domain and Interactors/UseCases/BusinessLogic differenciate does make a lot of sense. It feels natural and logical.

Andreas Grimm

unread,
Jan 24, 2014, 5:43:38 PM1/24/14
to clean-code...@googlegroups.com
On Wednesday, January 22, 2014 6:23:35 PM UTC+1, Bennie Copeland wrote:

annotation: In CleanArchitecture in addition to the entities the Interactors contain (only application specific instead of enterpize wide) (validation) business logic as well.
-> This leads me to further questions.
What if an application specific validation logic that conceptually belongs to a specific entity needs to be executed in several Interactors/UseCases? To what kind of component (outside of any entity) should this piece of functionality be extracted in order to stay DRY and where would it reside in the (folder) structure? I really can't imagine that it would be another Interactor because .. why would you potentially do an unnecessary mapping of data onto InteractorRequestDTOs again? We are behind the application boundary already and the logic that we want to call doesn't need to be called from outside the boundary and in addition it isn't necessarily a separate UseCase(Flow/Story).

Don't think that you are limited to the folder structure above. Every application is different and has different requirements. In this case, I might create a services folder (either at the root, or under the interactors folder)  and put the validation logic there. But this could also be looked at as another use case itself. 
And I don't see why a use case can't call another use case.
 
It totally can therefor should. "include / extend" UseCase. It's just that you'd feel like you unnecessarily have to jump some hoops if you'd for that reason have to do the object->DTO mapping again .. and again, one time for each UseCase call.
Could you thus conclude that a Boundary is needed only when a specific UseCase has to be accessible from the outside? .. and otherwise it was allowed to use a more lightweight way of executing the "functionality"/UseCase ??

 
This question is more of a general nature: As for entities setters (and getters) for private data fields should be avoided where possible, I assume application specific validation logic for such an entity (that resides in the interactors or in the above mentioned components in question) should be executed before the state-changing behaviour _of_ (or _on_) the entity is initiated?
..... that's another part that's kinda difficult to grasp: How to avoid setters on entity objects .. or let's say: when _application specific behaviour_ should be initiated, how do you implement behaviour affecting entities if it is not allowed to implement it for the (enterprize wide) entity object itself? Can it be done only by having some private field setters on the entity? .. Does the term "application specific _behaviour_" makes any sense then? .. Or can the term only be seen for a level as granular as to the Interactors but not any further (because using setters on the entities then would technically not be behaviour anymore)?

I'm not entirely sure I'm following the question. The entities can be viewed as being only as restrictive as the domain requires. It should allow the maximum flexibility inherent to the domain. The application layer cannot make the domain more flexible than it already is, but it can make it more restrictive to address the use cases. If the entities need to be more flexible than they already are, then the models are now flawed in light of the new information and understanding, and need to be updated. This shouldn't be viewed as a bad thing as now you have increased your knowledge and understanding of the domain. The application specific validation logic should happen before modifying the entity. There may be side effects to modifying the entity like event triggering. When the entity is modified, It can fire an event off that other entities may be registered to be notified which in turn causes them to modify some state. That would be a real mess to try and undo. :) As for setters, I prefer using setters whether the fields are private or not. Its the perfect place to put validation logic.

You totally got it. Thanks for the great answer. It helped me understand to a greater extend the differences between entities and interactors and the type of functionality that should go in each of them.
Reply all
Reply to author
Forward
0 new messages