Events are designed to decouple one area from another.
This sometimes involves some asynchronous behavior, which can be an additional feature, but is not mandatory. For example, if you want to provide rapid feedback to the user in a GUI, and a part of your code runs too slowly (unless it needs to be finished before providing feedback), then the regular call can execute fast codes, and create an event for the others, then provide GUI feedback without waiting for the event to be actually processed. This event is stored in a Queue, and one or more threads are processing that Queue at their own pace.
For synchronous events, it is really useful for inter-module communication, where the two modules don't have compile-time dependencies on each other. Both can know about an event class, and an "event router" :
- one module creates an event and call the router,
- the router knows (from previous configuration) what other module should receive it, and send it to the receiving module.
Neither module know about the other, thus the decoupling concept. Very good if both must be maintained separately :-)
Many variations exist, for some topics like:
- broadcasting to many receivers
- fail-over (if the receiver is down temporarily, it starts again ; the event will be delivered when the receiver is up and registered again)
- auditing : a technical module can receive events targeted at other modules, and log them
- ...
Modifying Domain objects via events seems a bit strange. Is the decoupling mentioned higher really justified?
However, I wouldn't give a definite opinion before understanding more precisely what you have in mind.