Distinguishing between UI command & domain commands

cqrsdesign-patternsmvvmnaming

I am building a WPF client application using the MVVM pattern that provides an interface on top of an existing set of business logic residing in a library which is shared with other applications. The business library followed a domain-driven architecture using CQRS to separate the read and write models (no event sourcing). The combination of technologies and patterns has brought up an interesting conundrum:

  • The MVVM pattern uses the command pattern for handling
    user-interaction with the view models. .NET provides an ICommand
    interface which is implemented by most MVVM frameworks, like MVVM
    Light's RelayCommand and Prism's DelegateCommand. For example, the view model would expose a number of command objects as properties that are bound to the UI and respond when the user performs actions like clicking buttons.
  • Many implementations of the CQRS use the command pattern to isolate
    and encapsulate individual behaviors. In my business library, we have implemented the write model as command / command-handler pairs. As such, when we want to do some work, such as create a new order, we 'issue' a command (CreateOrderCommand) which is routed to the command-handler responsible for executing the command.

This is great, clearly explained in many sources and I am good with it. However, take this scenario:

I have a ToolbarViewModel which exposes a CreateNewOrderCommand
property. This ICommand object is bound to a button in the UI. When
clicked, the UI command creates and issues a new CreateOrderCommand
object to the domain which is handled by the CreateOrderCommandHandler.

This is difficult to explain to other developers and I am finding myself getting tongue-tied because everything is a command.

I'm sure I'm not the first developer to have patterns overlap like this where the naming/terminology also overlap. How have you approached distinguishing your commands used in the UI from those used in the domain?

(Edit: I should mention that the business library is UI-agnostic, i.e. no UI technology-specific code exists, or will exists, in this library.)

Best Answer

I tend to resolve these naming conflicts by simply choosing different names.

Perhaps you have already started calling these things by different names internally, if so, have the codebase reflect that. If not, think of something (UserCommand vs WriteCommand, Command vs Request, Action vs Command...)

Basically, the overloading of the word "command" creates confusion, so change your terminology. It means deviating from the standard design pattern names, but that's better than constant confusion.

Terminology is not gospel. The terminology used by design patterns is supposed to make talking about the software easier. If it does the opposite, change it (and document that and why you did it)