DDD: DTOs and Parameter Objects - domain-driven-design

I'm modeling my domain using DDD/CQRS and I have a problem with naming things.
Assume that I have a Category aggregate that is a tree-like structure and I want to update the category tree:
class CategoryItemEntity {
Long guid;
String title;
List<CategoryItem> children;
Datetime createdAt;
Datetime updatedAt;
}
class CategoryItemParameterObject {
Long guid;
String title;
List<CategoryItem> children;
}
class CategoryAggregate {
Long guid;
List<CategoryItem> items;
void updateTree(List<CategoryItemParameterObject> items) {
// ...
}
}
My question is What should I call CategoryItemParameterObject? Is it a DTO or Something else? I also have a CategoryItemDTO on my read side. If I call it CategoryItemDTO would it make that confusing?
Is it ok to send commands directly to aggregates?

Is it a command? An entity?
Just thing about it's use and add to it a suffix/prefix that gives to who reads the code (not you, but who will do it 3, 6 or 12 months later) useful information about it's possible usage.
About the second question: yes, there's no rule that denies this. If the entity could handle the command itself, do it. I have an handler for a command that takes it, loads the entity and give the command to it. It works flawless and the meaning is really clear. Again, think about who will maintain the code, later, and do the thing that requires less thinking 'hops'.

Related

Multithreaded GUI update() methods

I'm begginer in multithreading. I recently started to writing something like multithreaded observer. I need some clarification.
Let's say I'm working with Subject, and I'm changing its state. Then Observers (in example - GUI widgets) have to be notified, so they could perform the update() method.
And there is my question: how am i handling those getValue() performed by many Observers? If it's just a getter for some variable, do i have to run it in new thread? Does it require any locking?
Or mayby there is a metod to just send those new value to GUI thread, and letting widgets there access those value. And again, can it be a single loop, or do i have to create another threads for every widget to get those value?
That's a difficult subject. Here are couple of things that will guide and help you with it.
Embrace eventual consistency. When one object updates on one thread, others will receive change notifications and update to the correct state eventually. Don't try to keep everything in sync all the time. Don't expect everything to be up to date all the time. Design your system to handle these situations. Check this video.
Use immutability especially for collections. Reading and writing to a collection from multiple threads can result in disasters. Don't do it. Use immutable collections or use snapshotting. Basically one object that will called from multiple thread will return a snapshot of the state of the collection. when a notification for a change is received, the reader (GUI in your case) will request a snapshot of the new state and update it accordingly.
Design rich Models. Don't use AnemicModels that have only setters and getters and let others manipulate them. Let the Model protect it's data and provide queries for it's state. Don't return mutable objects from properties of an object.
Pass data that describes changes with change notifications. This way readers (GUI) may sync their state only from the change data without having to read the target object.
Divide responsibility. Let the GUI know that it's single threaded and received notifications from the background. Don't add knowledge in your Model that it will be updated on a background thread and to know that it's called from the GUI and give it the responsibility of sending change requests to a specific thread. The Model should not care about stuff like that. It raises notifications and let subscribers handle them the way they need to. Let the GUI know that the change notification will be received on the background so it can transfer it to the UI thread.
Check this video. It describes different way you can do multithreading.
You haven't shown any code or specified language, so I'll give you an example in pseudo code using a Java/C# like language.
public class FolderIcon {
private Icon mIcon;
public Icon getIcon() { return mIcon; }
public FolderIcon(Icon icon) {
mIcon = icon;
}
}
public class FolderGUIElement : Observer {
private Folder mFolder;
private string mFolderPath;
public FolderGUIElement(Folder folder) {
mFolder = folder;
mFolderPath = mFolder.getPath();
folder.addChangeListener(this);
}
public void onSubjectChanged(change c) {
if(c instanceof PathChange) {
dispatchOnGuiThread(() => {
handlePathChange((PathChange)change);
});
}
}
handlePathChange(PathChange change) {
mFolderPath = change.NewPath;
}
}
public class Folder : Subject {
private string mPath;
private FolderIcon mIcon;
public string getPath() { return mPath; }
public FolderIcon getIcon() { return mIcon; }
public void changePath(string newPath) {
mPath = patnewPath;
notifyChanged(new PathChange(newPath));
}
public void changeIcon(FolderIcon newIcon) {
mIcon = newIcon;
notifyChanged(new IconChange(newIcon));
}
}
Notice couple of things in the example.
We are using immutable objects from Folder. That means that the GUI elements cannot get the value of Path or FolderIcon and change it thus affecting Folder. When changing the icon we are creating a brand new FolderIcon object instead of modifying the old one. Folder itself is mutable, but it uses immutable objects for it's properties. If you want you can use fully immutable objects. A hybrid approach works well.
When we receive change notification we read the NewPath from the PathChange. This way we don't have to call the Folder again.
We have changePath and changeIcon methods instead of setPath and setIcon. This captures the intent of our operations better thus giving our model behavior instead of being just a bag of getters and setters.
If you haven't read Domain Driven Design I highly recommend it. It's not about multithreading, but on how to design rich models. It's in my list of books that every developer should read. On concept in DDD is ValueObject. It's immutable and provide a great way to implement models and is especially useful in multithreaded systems.

How to model associations in DDD approach?

I'm learning DDD approach step by step with imaginary business domain by reading books of Eric Evans and Vaughn Vernon and I try to implement it using in my project using PHP (but it really doesn't matter here).
Recently I've been reading a lot of Aggregate, AggregateRoot and Entity patterns for models that should be defined by a domain. And, frankly, I'm not sure I understand all definitions well so I decided to ask my questions here.
At first I'd like to present my (sub)domain responsible for employees' holidays management which should make answers for my questions easier.
The most trivial case is that the Employee can be found in many Teams. When the employee decides to take few days off, he has to send a HolidaysRequest with metadata like type of holidays (like rest holidays, some days off to take care of his child, etc.), the acceptance status and of course time range when he's not going to appear in his office. Of couse HolidaysRequest should be aware of which Employee has sent the HolidaysRequest. I'd like also to find all HolidaysRequest that are sent by Employee.
I'm quite sure that things like DateRange or HolidayType are pure ValueObjects. It's quite clear for me. The problems start when I have to define boundries of entities. I may have bad practices of defining associations by nesting objects in entities, so, please, tell me finding out the definitions of responsibilities here.
What is an entity here? What should be an Aggregate and where's the place for AggregateRoot?
How to define associations between entities? E.g. an Employee can belong to multiple Teams or HolidaysRequest is authored by Employee and assigned to another Employee who can accept it. Should they be implemented as Aggregates?
Why I'm asking these questions? Because few weeks ago I've posted a question here and one of answers was to think about relations between Employee and Teams, that they should be in the single Aggreate called EmployeeInTeam but I'm not sure I understand it in proper way.
Thanks for any advice.
The main thing about DDD, is to put focus in the domain, that's why its called Domain Driven Design.
When you start asking about relationships, aggregates and entities without even deeply exploring what consists your domain, you're actually looking for database modeling instead of domain.
Please, I'm not saying you're asking wrong questions, nor criticising they, I think you're not wrong at all when trying to put in practice while studying.
I'm not DDD expert, I'm learning just like you, but I'm gonna try to help.
Start by thinking what situation's may arise about Holydays Management. When you have different rules for something, you could start by using strategies (I'm saying is the final solution).
Building a nice and meaningful domain, is very hard (at least for me). You write code. Test it. Have insights, throw your code way and rewrite it. Refactor it. In your software's lifecycle, you should put focus on domain, therefore you should be always improving it.
Start by coding (like a domain's draft) to see how it looks like. Let's exercise it. First of all, why do we need to manage this stuff? What problem are we trying to solve? Ahh, sometimes employees ask some days off, we want to control it. We may approve or not, depending on the reason they want "holyday", and how is our team status. If we decline and they still go home, we'll late decide whether we fire or discount in salary. Enforcing ubiquitous language, let's express in code this problem:
public interface IHolydayStrategy
{
bool CanTakeDaysOff(HolydayRequest request);
}
public class TakeCareOfChildren : IHolydayStrategy
{
public bool CanTakeDaysOff(HolydayRequest request)
{
return IsTotalDaysRequestedUnderLimit(request.Range.TotalDays());
}
public bool IsTotalDaysRequestedUnderLimit(int totalDays)
{
return totalDays < 3;
}
}
public class InjuredEmployee : IHolydayStrategy
{
public bool CanTakeDaysOff(HolydayRequest request)
{
return true;
}
}
public class NeedsToRelax : IHolydayStrategy
{
public bool CanTakeDaysOff(HolydayRequest request)
{
return IsCurrentPercentageOfWorkingEmployeesAcceptable(request.TeamRealSize, request.WorkingEmployees)
|| AreProjectsWithinDeadline(request.Projects);
}
private bool AreProjectsWithinDeadline(IEnumerable<Project> projects)
{
return !projects.Any(p => p.IsDeadlineExceeded());
}
private bool IsCurrentPercentageOfWorkingEmployeesAcceptable(int teamRealSize, int workingEmployees)
{
return workingEmployees / teamRealSize > 0.7d;
}
}
public class Project
{
public bool IsDeadlineExceeded()
{
throw new NotImplementedException();
}
}
public class DateRange
{
public DateTime Start { get; set; }
public DateTime End { get; set; }
public int TotalDays()
{
return End.Subtract(Start).Days;
}
public bool IsBetween(DateTime date)
{
return date > Start && date < End;
}
}
public enum HolydayTypes
{
TakeCareOfChildren,
NeedToRelax,
BankOfHours,
Injured,
NeedToVisitDoctor,
WannaVisitDisney
}
public class HolydayRequest
{
public IEnumerable<Project> Projects { get; internal set; }
public DateRange Range { get; set; }
public HolydayTypes Reason { get; set; }
public int TeamRealSize { get; internal set; }
public int WorkingEmployees { get; internal set; }
}
Here is how I quickly wrote this:
Holydays may be granted or not, depending on the situation and
reason, let's create a IHolydayStrategy.
Created an empty (propertyless) HolydayRequest class.
For each possible reason, let's create a different strategy.
If the reason is to take care of children, they can take days off if
the total days request is under a limit.
If the reason is because the employee has been injured, we have no
choice other than allowing the request.
If the reason is because they need to relax, we check if we have an
acceptable percentage of working employees, or if projects are within
deadline.
As soon as I needed some data in the strategy, I used CTRL + . to
automagically create properties in HolydayRequest.
See how I don't even know how these stuff are going to be stored/mapped? I just wrote code to solve a problem, and get piece of information needed to resolve it.
Obviously this is not the final domain, is just a draft. I might take away this code and rewrite, if needed, no feelings for it yet.
People may think it's useless to create an InjuredEmployee class just to always return true, but the point here is to make use of ubiquitous language, to make things as explicit as possible, anyone would read and understand the same thing: "Well, if we have an injured employee, they are always allowed to take days off, regardless of the team's situation and how many days they need.". One of the problems this concept in DDD solves is the misunderstanding of terms and rules between developers, product owners, domain experts, and other participants.
After this, I would start writing some tests with mock data. I might refactor code.
This "3":
public bool IsTotalDaysRequestedUnderLimit(int totalDays)
{
return totalDays < 3;
}
and this "0.7d":
private bool IsCurrentPercentageOfWorkingEmployeesAcceptable(int teamRealSize, int workingEmployees)
{
return workingEmployees / teamRealSize > 0.7d;
}
are specifications, In my point of view, which shouldn't reside in a strategy. We might apply Specification Pattern to make things decoupled.
After we get to a reasonably initial solution with passed tests, now let's think how should we store it. We might use the final defined classes (such as Team, Project, Employee) here to be mapped by an ORM.
As soon as you started writing your domain, relationships will arise between your entities, that's why I usually don't care at all how the ORM will persist my domain, and what is Aggregate at this point.
See how I didn't create an Employee class yet, even though it sounds very important. That's why we shouldn't start by creating entities and their properties, because it's the exact same thing as creating tables and fields.
Your DDD turns into Database Driven Design that way, we don't want this. Of course, eventually we'll make the Employee, but let's take step by step, create only when you need it. Don't try to start modeling everything at once, predicting all entities you're going to need. Put focus on your problem, and how to solve it.
About your questions, what is entity and what is aggregate, I think you're not asking the definition of them, but whether Employee is considered one or other, considering your domain. You'll eventually answer yourself, as soon as your domain start being revealed by your code. You'll know it when you started developing your Application Layer, which should have the responsibility of loading data and delegating to your domain. What data my domain logic expects, from where do I start querying.
I hope I helped someone.

Defining aggregate roots when invariants exist within a list

I'm doing a family day care app, and thought I'd try DDD/CQRS/ES for it, but I'm running into issues with designing the aggregates well. The domain can be described pretty simply:
A child gets enrolled
A child can arrive
A child can leave
The goal is to track the times of the visits, generate invoices, put notes (eg. what was had for lunch, injuries etc.) against the visits. These other actions will be, by far, the most common interaction with the system, as a visit starts once a day, but something interesting happens all the time.
The invariant I'm struggling with is:
A child cannot arrive if they are already here
As far as I can see, I have the following options
1. Single aggregate root Child
Create a single Child aggregate root, with the events ChildEnrolled, ChildArrived and ChildLeft
This seems simple, but since I want each other event to be associated with a visit, it means the visit would be an entity of the Child aggregate, and every time I want to add a note or anything, I have to source all the visits for that child, ever. Seems inefficient and fairly irrelevant - the child itself, and every other visit, simply isn't relevant to what the child is having for lunch.
2. Aggregate Roots for Child and Visit
Child would source just ChildEnrolled, and Visit would source ChildArrived and ChildLeft. In this case, I don't know how to maintain the invariant, besides having the Visit take in a service for just this purpose, which I've seen is discouraged.
Is there another way to enforce the invariant with this design?
3. It's a false invariant
I suppose this is possible, and I should protect against multiple people signing in the same child at the same time, or latency meaning the use hits the 'sign in' button a bunch of times. I don't think this is the answer.
4. I'm missing something obvious
This seems most likely - surely this isn't some special snowflake, how is this normally handled? I can barely find examples with multiple ARs, let alone ones with lists.
Aggregates
You're talking heavily about Visits and what happened during this Visit, so it seems like an important domain-concept of its own.
I think you would also have a DayCareCenter in which all cared Children are enrolled.
So I would go with this aggregate-roots:
DayCareCenter
Child
Visit
BTW: I see another invariant:
"A child cannot be at multiple day-care centers at the same time"
"Hits the 'sign in' button a bunch of times"
If every command has a unique id which is generated for every intentional attempt - not generated by every click (unintentional), you could buffer the last n received command ids and ignore duplicates.
Or maybe your messaging-infrastructure (service-bus) can handle that for you.
Creating a Visit
Since you're using multiple aggregates, you have to query some (reliable, consistent) store to find out if the invariants are satisfied.
(Or if collisions are rarely and "canceling" an invalid Visit manually is reasonable, an eventual-consistent read-model would work too...)
Since a Child can only have one current Visit, the Child stores just a little information (event) about the last started Visit.
Whenever a new Visit should be started, the "source of truth" (write-model) is queried for any preceeding Visit and checked whether the Visit was ended or not.
(Another option would be that a Visit could only be ended through the Child aggregate, storing again an "ending"-event in Child, but this feels not so good to me...but that's just a personal opinion)
The querying (validating) part could be done through a special service or by just passing in a repository to the method and directly querying there - I go with the 2nd option this time.
Here is some C#-ish brain-compiled pseudo-code to express how I think you could handle it:
public class DayCareCenterId
{
public string Value { get; set; }
}
public class DayCareCenter
{
public DayCareCenter(DayCareCenterId id, string name)
{
RaiseEvent(new DayCareCenterCreated(id, name));
}
private void Apply(DayCareCenterCreated #event)
{
//...
}
}
public class VisitId
{
public string Value { get; set; }
}
public class Visit
{
public Visit(VisitId id, ChildId childId, DateTime start)
{
RaiseEvent(new VisitCreated(id, childId, start));
}
private void Apply(VisitCreated #event)
{
//...
}
public void EndVisit()
{
RaiseEvent(new VisitEnded(id));
}
private void Apply(VisitEnded #event)
{
//...
}
}
public class ChildId
{
public string Value { get; set; }
}
public class Child
{
VisitId lastVisitId = null;
public Child(ChildId id, string name)
{
RaiseEvent(new ChildCreated(id, name));
}
private void Apply(ChildCreated #event)
{
//...
}
public Visit VisitsDayCareCenter(DayCareCenterId centerId, IEventStore eventStore)
{
// check if child is stille visiting somewhere
if (lastVisitId != null)
{
// query write-side (is more reliable than eventual consistent read-model)
// ...but if you like pass in the read-model-repository for querying
if (eventStore.OpenEventStream(lastVisitId.Value)
.Events()
.Any(x => x is VisitEnded) == false)
throw new BusinessException("There is already an ongoning visit!");
}
// no pending visit
var visitId = VisitId.Generate();
var visit = new Visit(visitId, this.id, DateTime.UtcNow);
RaiseEvent(ChildVisitedDayCenter(id, centerId, visitId));
return visit;
}
private void Apply(ChildVisitedDayCenter #event)
{
lastVisitId = #event.VisitId;
}
}
public class CommandHandler : Handles<ChildVisitsDayCareCenter>
{
// http://csharptest.net/1279/introducing-the-lurchtable-as-a-c-version-of-linkedhashmap/
private static readonly LurchTable<string, int> lastKnownCommandIds = new LurchTable<string, bool>(LurchTableOrder.Access, 1024);
public CommandHandler(IWriteSideRepository writeSideRepository, IEventStore eventStore)
{
this.writeSideRepository = writeSideRepository;
this.eventStore = eventStore;
}
public void Handle(ChildVisitsDayCareCenter command)
{
#region example command douplicates detection
if (lastKnownCommandIds.ContainsKey(command.CommandId))
return; // already handled
lastKnownCommandIds[command.CommandId] = true;
#endregion
// OK, now actual logic
Child child = writeSideRepository.GetByAggregateId<Child>(command.AggregateId);
// ... validate day-care-center-id ...
// query write-side or read-side for that
// create a visit via the factory-method
var visit = child.VisitsDayCareCenter(command.DayCareCenterId, eventStore);
writeSideRepository.Save(visit);
writeSideRepository.Save(child);
}
}
Remarks:
RaiseEvent(...) calls Apply(...) instantly behind the scene
writeSideRepository.Save(...) actually saves the events
LurchTable is used as a fixed-sized MRU-list of command-ids
Instead of passing the whole event-store, you could make a service for it if you if benefits you
Disclaimer:
I'm no renowned expert. This is just how I would approach it.
Some patterns could be harmed during this answer. ;)
It sounds like the "here" in your invariant "A child cannot arrive if they are already here" might be an idea for an aggregate. Maybe Location or DayCareCenter. From there, it seems trivial to ensure that the Child cannot arrive twice, unless they have previously left.
Of course, then this aggregate would be pretty long-lived. You may then consider an aggregate for a BusinessDay or something similar to limit the raw count of child arrivals and departures.
Just an idea. Not necessarily the way to solve this.
I would try to base the design on reality and study how they solve the problem without software.
My guess is they use a notebook or printed list and start every day with a new sheet, writing today's date and then taking notes for each child regarding arrival, lunch etc. The case with kids staying the night shouldn't be a problem - checking in day 1 and checking out day 2.
The aggregate root should focus on the process (in your case daily/nightly per-child caring) and not the participating data objects (visit, child, parent, etc.).
I'm missing something obvious
This one; though I would quibble with whether or not it is obvious.
"Child" probably should not be thought of as an aggregate in your domain model. It's an entity that exists outside your model. Put another way, your model is not the "book of record" for this entity.
The invariant I'm struggling with is:
A child cannot arrive if they are already here
Right. That's a struggle, because your model doesn't control when children arrive and leave. It's tracking when those things happen in some other domain (the real world). So your model shouldn't be rejecting those events.
Greg Young:
The big mental leap in this kind of system is to realize that
you are not the book of record. In the warehouse example the
*warehouse* is the book of record. The job of the computer
system is to produce exception reports and estimates of what
is in the warehouse
Think about it: the bus arrives. You unload the children, scan their bar codes, and stick them in the play room. At the end of the day, you reverse the process -- scanning their codes as you load them onto the bus. When the scanner tries to check out a child who never checked in, the child doesn't disappear.
Your best fit, since you cannot prevent this "invariant violation", is to detect it.
One way to track this would be an event driven state machine. The key search term to use is "process manager", but in older discussions you will see the term "saga" (mis)used.
Rough sketch: your event handler is listening to these child events. It uses the id of the child (which is still an entity, just not an aggregate), to look up the correct process instance, and notifies it of the event. The process instance compares the event to its own state, generates new events to describe the changes to its own state, and emits them (the process manager instance can be re-hydrated from its own history).
So when the process manager knows that the child is checked in at location X, and receives an event claiming the child is checked in at location Y, it records a QuantumChildDetected event to track the contingency.
A more sophisticated process manager would also be acting on ChildEnrolled events, so that your staff knows to put those children into quarantine instead of into the playroom.
Working back to your original problem: you need to think about whether Visits are aggregates that exist within your domain model, or logs of things that happen in the real world.

DDD - Invalidating expirable

Currently diving into DDD and i've read most of the big blue book of Eric Evans. Quite interesting so far :)
I've been modeling some aggregates where they hold a collection of entities which expire. I've come up with a generic approach of expressing that:
public class Expirable<T>
{
public T Value { get; protected set; }
public DateTime ValidTill { get; protected set; }
public Expirable(T value, DateTime validTill)
{
Value = value;
ValidTill = validTill;
}
}
I am curious what the best way is to invalidate an Expirable (nullify or omit it when working in a set). So far I've been thinking to do that in the Repository constructor since that's the place where you access the aggregates from and acts as a 'collection'.
I am curious if someone has come up with a solution to tackle this and I would be glad to hear it :) Other approaches are also very welcome.
UPDATE 10-1-2013:
This is not DDD with the CQRS/ES approach from Greg Young. But the approach Evans had, since I just started with the book and the first app. Like Greg Young said, if you have to make good tables, you have to make a few first ;)
There are probably multiple ways to approach this, but I, personally, would solve this using the Specification pattern. Assuming object expiration is a business rule that belongs in the domain, I would have a specification in addition to the class you have written. Here is an example:
public class NotExpiredSpecification
{
public bool IsSatisfiedBy(Expirable<T> expirableValue)
{
//Return true if not expired; otherwise, false.
}
}
Then, when your repositories are returning a list of aggregates or when performing any business actions on a set, this can be utilized to restrict the set to un-expired values which will make your code expressive and keep the business logic within the domain.
To learn more about the Specification pattern, see this paper.
I've added a method to my abstract repository InvalidateExpirable. An example would be the UserRepository where I remove in active user sessions like this: InvalidateExpirable(x => x.Sessions, (user, expiredSession) => user.RemoveSession(expiredSession));.
The signature of InvalidateExpirable looks like this: protected void InvalidateExpirable<TExpirableValue>(Expression<Func<T, IEnumerable<Expirable<TExpirableValue>>>> selector, Action<T, Expirable<TExpirableValue>> remover). The method itself uses reflection to extract the selected property from the selector parameter. That property name is glued in a generic HQL query which will traverse over the set calling the remove lambda. user.RemoveSession will remove the session from the aggregate. This way the I keep the aggregate responsible for it's own data. Also in RemoveSession an domain event is raised for future cases.
See: https://gist.github.com/4484261 for an example
Works quite well sofar, I have to see how it works further down in the application though.
Have been reading up on DDD with CQRS/ES (Greg Young approach) and found a great example on the MSDN site about CQRS/ES: http://msdn.microsoft.com/en-us/library/jj554200.aspx
In this example they use the command message queue to queue a Expire message in the future, which will call the Aggregate at the specified time removing/deactivate the expirable construct from the aggregate.

Domain Driven Design - Access modifier for domain entities

I am just starting out with domain driven design and have a project for my domain which is structured like this:
Domain
/Entities
/Boundaries
/UserStories
As I understand DDD, apart from the boundaries with which the outside world communicates with the domain, everything in the domain should be invisble. All of the examples I have seen of entity classes within a domain have a public access modifer, for example here I have a entity named Message:
public class Message
{
private string _text;
public string Text
{
get { return _text; }
set { _text = value; }
}
public Message()
{
}
public bool IsValid()
{
// Do some validation on text
}
}
Would it not be more correct if the entity class and its members were marked as internal so it is only accessible within the domain project?
For example:
internal class Message
{
private string _text;
internal string Text
{
get { return _text; }
set { _text = value; }
}
internal Message()
{
}
internal bool IsValid()
{
// Do some validation on text
}
}
I think there's a confusion here: the Bounded Context is a concept which defines the context in which a model is valid there aren't classes actualy named Boundary. Maybe those are objects for anti corruption purposes, but really the Aggregate Root should deal with that or some entry point in the Bounded Context.
I wouldn't structure a Domain like this, this is artificial, you should structure the Domain according to what make sense in the real world process. You're using DDD to model a real world process in code and I haven't heard anyone outside software devel talking aobut Entities or Value Objects. They talk about Orders, Products, Prices etc
Btw that Message is almost certain a value object, unless the Domain really needs to identify uniquely each Message. Here the Message is a Domain concept, I hope you don't mean a command or an event. And you should put the validation in the constructor or in the method where the new value is given.
In fairness this code is way to simplistc, perhaps you've picked the wrong example. About the classes being internal or public, they might be one or another it isn't a rule, it depends on many things. At one extreme you'll have the approach where almost every object is internal but implements a public interface common for the application, this can be highly inefficient.
A rule of the thumb: if the class is used outside the Domain assembly make it public, if it's something internally used by the Domain and/or implements a public interface, make it internal.

Resources