Command vs. Event in Domain Driven Design

Recently the team I have been part of have decided to adopt domain driven design to the application we have been working on due to multiple reasons. This decision has led me to delving deeper into the best practices of domain driven design and its key concepts.

Here I will try and articulate the differences between a command and an event within the scope of the domain layer of an application.

Commands and events are both simple domain structures that contain solely data for reading. That means they contain no behaviour or business logic.

A command is an object that is sent to the domain for a state change which is handled by a command handler. They should be named with a verb in an imperative mood plus the aggregate name which it operates on. Such request can be rejected due to the data the command holds being invalid/inconsistent. There should be exactly 1 handler for each command. Once the command has been executed, the consumer can then carry out whatever the task is depending on the output of the command.

An event is a statement of fact about what change has been made to the domain state. They are named with the aggregate name where the change took place plus the verb past-participle. An event happens off the back of a command. A command can emit any number of events. The sender of the event does not care who receives it or whether it has been received at all.

These terms are mere concepts and is technology independent. Below is an example in C# in an order management domain, which is mainly inspired by Gregory Young’s m-r sample.

// Event store is responsible for dispatching events, implementation details omitted
public interface IEventStore
{
void DispatchEvent(long aggregateId, Event @event);
}
public class PlaceOrderCommand
{
public int OrderId { get; }
public PlaceOrderCommand(int orderId)
{
OrderId = orderId;
}
}
public class OrderPlacedEvent
{
public int OrderId { get; }
public DateTime OrderDate { get; }
public OrderPlacedEvent(int orderId, DateTime orderDate)
{
OrderId = orderId;
OrderDate = orderDate;
}
}
public class OrderCommandHandler
{
private readonly IEventStore _eventStore;
public OrderCommandHandler(IEventStore eventStore)
{
_eventStore = eventStore;
}
    public void Handle(PlaceOrderCommand command)
{
// operations omitted
_eventStore.DispatchEvent(command.OrderId, new OrderPlacedEvent(command.OrderId, DateTime.UtcNow));
}
}

The intent of a command and that of an event is completely different. The former makes the request to execute, while the latter informs the execution has been done.