Avoiding of Value Object inside Domain Events

1,814 views
Skip to first unread message

B.A

unread,
Oct 4, 2013, 7:14:03 AM10/4/13
to ddd...@googlegroups.com
Hi,

I often read in this group that it is bad to insert Value Object in domain event.
But in case of Event sourcing approach, it seems that easier to use value object inside event, otherwise,
you have to convert value object to DTO and reverse operation (value object to dto to apply event from aggregate root,
and dto to value object to read event inside aggregate root in order to apply modification in internal fields)

Simplified Exemple :

public class Organization [AR]
{
    private ContactAddress contactAddress;
....

    public void modifyContactAddress(ContactAddresss contactAddress)
    {
        // here somme preconditions validation
        ...
        apply(new ContactAddressModifiedEvent(new ContactAddressDTO(contactAddress.name, contactAddress.email, ... )));
    }
   
    @EventHandler
    void handle(ContactAddressModifiedEvent event)
    {
        this.contactAddress = new ContactAddress(event.getContactAddressDTO().name, event.getContactAddressDTO().email, ...);
    }
}

Obviously, this is not a good example here, because it is too simple, but if you have to call a method on aggregate with more complex VO objects,
you have to use this artificial conversion, just to avoid VO in event.
 
I have noticed that In IDDD sample project, made by Vaughn Vernon (Implementing DDD book), he puts direclty VO inside domain event.

How can you solve this problem ?

Best regards,

Baptiste.

Greg Young

unread,
Oct 4, 2013, 8:29:23 AM10/4/13
to ddd...@googlegroups.com
What happens when you rename a field in your value object?

Cheers,

Greg
--
You received this message because you are subscribed to the Google Groups "DDD/CQRS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dddcqrs+u...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


--
Le doute n'est pas une condition agréable, mais la certitude est absurde.

B.A

unread,
Oct 4, 2013, 8:44:50 AM10/4/13
to ddd...@googlegroups.com
You can create an event upcaster (for example, with axonframework : http://www.axonframework.org/docs/2.0/single.html#event-upcasting).
The domain event concerned by this value object is also a domain concern, so i suppose that it is normal to refactor the domain event (or create a new version) when the value object is refactored ?
To unsubscribe from this group and stop receiving emails from it, send an email to dddcqrs+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/groups/opt_out.

Greg Young

unread,
Oct 4, 2013, 9:01:35 AM10/4/13
to ddd...@googlegroups.com
So every time someone refractors a value object you create up casters? What if someone forgets?

No it is not common to change the event as well when changing a value object. Events are wire contracts value objects are not better to keep them separate.
To unsubscribe from this group and stop receiving emails from it, send an email to dddcqrs+u...@googlegroups.com.

For more options, visit https://groups.google.com/groups/opt_out.

B.A

unread,
Oct 4, 2013, 9:13:14 AM10/4/13
to ddd...@googlegroups.com
But if i have to add or modify a field in my ContactAddress, even if you don't use the VO inside the event, i have to modify the event in order to add/modify this field in the constructor of my event (otherwise, my read model will never see modification of the modified field). So i have the same refactoring problem, no ?

Greg Young

unread,
Oct 4, 2013, 9:53:46 AM10/4/13
to ddd...@googlegroups.com
That's one kind of change (adding) what about other kinds of changes?
To unsubscribe from this group and stop receiving emails from it, send an email to dddcqrs+u...@googlegroups.com.

For more options, visit https://groups.google.com/groups/opt_out.

Phillip Cleveland

unread,
Oct 4, 2013, 9:56:57 AM10/4/13
to ddd...@googlegroups.com
When you start thinking of other applications as the consumers of your events downstream then the refactor scenario becomes very real and tedious. Imagine having to recompile and rerelease app 2 just because app 1 refactored a VO. 

Sent from my iPad

@yreynhout

unread,
Oct 4, 2013, 9:59:29 AM10/4/13
to ddd...@googlegroups.com
Different paces of change ;-) Refactor relentlessly inside the boundary. Try to keep contracts stable at the boundary.

B.A

unread,
Oct 4, 2013, 10:04:42 AM10/4/13
to ddd...@googlegroups.com
So, if i understand the idea : every Domain Event definition does not contain any reference of domain class at all ?
So every domain events are out of boundary of the domain itself ?

@yreynhout

unread,
Oct 4, 2013, 10:53:15 AM10/4/13
to ddd...@googlegroups.com
No, that's not what I'm saying. You make it sound like the events don't pertain to the domain. They do. 

B.A

unread,
Oct 4, 2013, 11:28:46 AM10/4/13
to ddd...@googlegroups.com
I would mean that in every event domain classes, you never reference domain types, just primitive types ?
Technically speaking, i should be able to compile all my domain events classes without domain api reference ?

sebastian

unread,
Oct 4, 2013, 11:33:20 AM10/4/13
to ddd...@googlegroups.com
You should publish a public wire protocol contract for your events. Perhaps this is a protobuf document. Perhaps a .NET assembly with POCOs/DTOs in it. But you should have some freedom to refactor the real value objects you use inside your domain and leave the events alone as far as possible.

Honestly, it's like defining database tables. Your domain objects shouldn't be data rows. You can refactor your domain objects, you can refactor your database tables, but you should do that for different reasons.


On Fri, Oct 4, 2013 at 5:28 PM, B.A <baptist...@gmail.com> wrote:
I would mean that in every event domain classes, you never reference domain types, just primitive types ?
Technically speaking, i should be able to compile all my domain events classes without domain api reference ?

--
You received this message because you are subscribed to the Google Groups "DDD/CQRS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dddcqrs+u...@googlegroups.com.

For more options, visit https://groups.google.com/groups/opt_out.



--
Sebastian Good

Greg Young

unread,
Oct 4, 2013, 1:23:22 PM10/4/13
to ddd...@googlegroups.com
better do them in .proto files or xsd or some other schema definition language

Johanna Belanger

unread,
Oct 4, 2013, 3:40:24 PM10/4/13
to ddd...@googlegroups.com
I still don't understand why it makes sense to use the wire contracts inside the domain. Why not translate to and from the wire contract at the boundary when it's helpful? (Considering the event storage to be outside of the boundary.)

Stefano Ottaviani

unread,
Oct 7, 2013, 4:57:02 AM10/7/13
to ddd...@googlegroups.com
Do you avoid Value Objects also in commands? If the client(s) and the domain model are updated in different moments (it could happen in several situations), the same problem could happen also there.

B.A

unread,
Oct 7, 2013, 5:09:30 AM10/7/13
to ddd...@googlegroups.com
I think it is better to have no reference of domain object in command, but that looks more logical for me, because command are not domain concept.

I have one more question :
Do I have to consider a simple enum class as a Value Object, and not use it in my domain event also ? So do i have to duplicate this enum concept to publish it to events, or cast the enum value to a string value ?

public enum OrganizationType { TYPE_1, TYPE_2, TYPE_3 ]  --> Value Object ?
...

new OrganizationCreatedEvent("ABCD1", "TYPE_1" (or OrganizationType.TYPE_1 ??), ...)

Best regards,

Baptiste.

Greg Young

unread,
Oct 7, 2013, 5:23:16 AM10/7/13
to ddd...@googlegroups.com
I'd be less militant in commands. The real question is what is your client? Is it in the same tier or in a different tier? If in the same tier then it's no problem, if in a different tier treat as schema
To unsubscribe from this group and stop receiving emails from it, send an email to dddcqrs+u...@googlegroups.com.

For more options, visit https://groups.google.com/groups/opt_out.

B.A

unread,
Oct 7, 2013, 7:25:48 AM10/7/13
to ddd...@googlegroups.com
Are clients not always in a different tier ?
In my case, i have  web clients (with rpc/gwt and/or rest protocol).

Greg Young

unread,
Oct 7, 2013, 7:27:06 AM10/7/13
to ddd...@googlegroups.com
You could very easily have a single tier (think about in memory of a webserver)


To unsubscribe from this group and stop receiving emails from it, send an email to dddcqrs+u...@googlegroups.com.

For more options, visit https://groups.google.com/groups/opt_out.
Reply all
Reply to author
Forward
0 new messages