7

Can CQRS pattern exist and/or work without mediator pattern?

I mean there are always commands and these commands have to be dispatched somehow to the handlers that perform some logic on them.

Does it mean that CQRS pattern depend on mediator pattern in order to work?

Every example I see with CQRS uses mediator pattern, does it mean it's integral part of this pattern?

Or it can work without using mediator pattern at all?

But it doesn't make much sense then...

0

2 Answers 2

15

Command Query Responsibility Separation (CQRS) separates reading and writing into two different models.

A "conventional" architecture looks like this:

![Diagram of a conventional architecture (Fowler)

A CQRS architecture looks like this:

![Diagram of a CQRS Architecture (Fowler)

Notice how the CQRS diagram has two endpoints servicing the UI, not just one?

The Mediator pattern defines an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently.

enter image description here

The Mediator Pattern ensures that components don't call each other explicitly, but instead do so through calls to a mediator. In the following example, the Mediator registers all Components and then calls their SetState methods.

public interface IComponent
{
    void SetState(object state);
}

public class Component1 : IComponent
{
    public void SetState(object state)
    {
        throw new NotImplementedException();
    }
}

public class Component2 : IComponent
{
    public void SetState(object state)
    {
        throw new NotImplementedException();
    }
}

// Mediates the common tasks
public class Mediator
{
    public IComponent Component1 { get; set; }
    public IComponent Component2 { get; set; }

    public void ChangeState(object state)
    {
        this.Component1.SetState(state);
        this.Component2.SetState(state);
    }
}

Mediators lend themselves naturally to the Observer Pattern and the Event Aggregator Pattern, since events are a natural way to register components with a mediator:

enter image description here

Notice how similar this diagram of the Observer Pattern is with the Mediator pattern diagram above?

So what does the Mediator Pattern have to do with CQRS?

Not much, really.

Well, other than the fact that you can use a Mediator with CQRS, and an Observer Pattern with the mediator, and probably a half-dozen other useful software patterns with both.

Further Reading
Command Query Responsibility Segregation by Martin Fowler
CQRS Example in C# at MSDN
Command query responsibility segregation on Wikipedia
Observer Pattern on Sourcemaking.com
Event Aggregator (Fowler)

0
2

Yes. No mediator is required.

Assume the following interface:

public interface ICommandHandler<in TCommand> where TCommand : ICommand
{
    void Execute(TCommand command);
}

Now you have the following command:

public class CreateCustomer : ICommand { /* ... */ }

And a controller (example from ASP.NET MVC):

public CustomerController
{
    CustomerController(ICommandHandler<CreateCustomer> handler) { Handler = handler; }

    public ActionResult CreateCustomer(CreateCustomer model)
    {
        if (!ModelState.IsValid) { return View(); }
        Handler.Execute(model);
        return View();
    }
}

The dependency injection will handle the creation of the command handler. If you want to apply additional behavior (e.g. logging) to the command execution, you can implement an interceptor within the dependency injection. The object could be a decorator including the orgiginal command handler or a proxy submitting the command to web service. All OOP stuff is possible via injection.

An alternative could be a factory pattern:

    public ActionResult CreateCustomer(CreateCustomer model)
    {
        var handler = HandlerFactory.CreateHandlerFor<CreateCustomer>();
        handler.Execute(model);
        return View();
    }

Works fine (if you like factories).

A mediator is just a way to decouple two objects. The advantage is you just have to inject the mediator instead of multiple required command handlers (in comparision to the dependency injection) and you do not have to hold a local copy of the created command handler (in comparision to the factory pattern).

But a mediator has also disadvantages. For instance you cannot control, that the CustomerController calls the command CreateProduct. By injection only specific command handlers, you can limit the commands a controller can create (if you want to).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.