I, COMMAND

Part I: FRONTEND

https://github.com/niwrA/CommandBlog/tree/master

In our continued overview of useful Agile Development practices, we turn our attention to the Command pattern. When developing in an Agile project (or any project with a UI really), Command Query (Responsibility) Separation can be your very best of friends. There are few patterns that are as flexible and easy to maintain, refactor, secure and test, and it scales well from the smallest of Micro services to the largest of Domain Driven Design projects. Equally, there are almost no patterns that can track a user’s actions in quite the same way, which can easily translate into a much better user experience also by providing the development team with better data about user behavior.

The basic reason for command and query separation is the understanding that consuming data and editing data are two quite different things, and should be treated as such. For instance, the query part of an application retrieves (a lot of) information from a variety of sources, some perhaps internal, other external, in various different formats (list, details, part, whole, per tab, per module, etc.) to various different clients (web, smartphone, desktop, other systems). Whereas updating data often has completely different requirements and responsibilities: tighter security, transaction management, locking data on update, notifications and triggering other processes, etcetera, and typically with much less data being transferred to the backend.

A very good example of this difference is searching the web for a recipe, selecting one from a (probably large) number of sites, cooking it, and then rating the recipe on the site where you found it. A site like Google basically indexes all of the web, so your read/query part of this story is basically everything everyone has access to at any given time on the internet. On the other hand, this tiny website has this one little recipe, and you click one a box with some stars and maybe leave a review, which then ends up adding a count, a user id, and a text field in a little table on a little database on a little server somewhere completely different. Google may or may not index this review again sooner or later, but clearly these are code bases that never even get near each other.

Although not nearly all applications are written like this, most of them will benefit from a similar approach, and Agile development will benefit even more. Let’s look at an example of how this can work.

Studying a Case: Note App

Say you wanted to write a program that stores notes on a computer or smartphone. At the most basic level, there is very little you need to be able to do for this. You need a bit of UI, where a user can create a note and type some text on it, and the user probably wants to see previous notes as well, and finally the user will likely want to be able to see them again tomorrow. Finally, the ability to delete a note pretty much rounds out the core functionality one would expect.

Wrapping it up as a very primitive user story, we could say the following:

1.    As a user, I want to be able to create a new Note

2.    As a user, I want to be able to see all the Notes I created

3.    As a user, I want to be able to remove a Note

4.    As a user, I want to be able to add text to a Note

5.    As a user, I want to be able to see my Notes again whenever I reopen the App

6.    As a user, I want to be able to text-search my Notes

Right there, we can see that half are about creating and updating Notes, and the other half are about reading the Notes. Note right away that for 5, being able to see my Notes again when I reopen the App, this implies that we have to store our Notes somewhere and so we need some kind of Repository. But also, when implementing these stories, we don’t need it before then.

For 6, note that we may not even have to write this functionality in our own App – perhaps the user is more than happy if the OS is able to find the Note in its generic search, rather than having a dedicated search in the App itself.

From User Story to User Interface

At this point, you will find many a developer starting to draw a data model, often even thinking how to store this in a database. But a UI designer will typically focus just on what UI components to build and how the user will interact with them. In this time of hugely different options in database storage (SQL to NoSQL, In Memory databases, WebApis, Service Busses, etc.), it is probably wiser than ever to focus on the UI first and start without a backend altogether. And beyond that initial beginning, you can proceed with having a very simple one that can easily be switched out for different technologies suiting the specific demands of the UI. We will see how here too, the Command pattern makes life much easier.

Identifying the UI Components

So, let’s make an inventory of the UI components we need. It’s clear that we need an ‘Add’ input of some sort, an Edit view of a Note so we can change text on it, an input to Delete a note, and some List type of control to display all the notes we created and where we can select a Note to take it into Edit an edit view or Delete it.

How this is actually implemented can differ per platform – do I want to swipe to delete on smartphone, or click a delete button on an item on a purely mouse driven platform, or support both (as would be a typical Windows 10 universal app approach).

Desktop and Mobile very different worlds? Not for the controller: code in the following example is just as appropriate for, say, Angular 1 or 2, as it is for WPF, UWP or Xamarin, or even MVC or WebApi Controllers.

Already you can see that the actions on a controller are likely to be platform independent, and you could and probably should design those cross platform, even if you don’t actually implement multiple platforms. This clearly indicates that there is a natural border for separation of concern here. That’s not to say there won’t be any dependencies whatsoever of course – if your UI is showing data as it loads, that will be different from when the UI can only handle data that has been loaded completely. This is particularly of concern for tables, where server side paging support and sorting can be quite different from doing the same client side. But until we find ourselves where platform needs diverge, we can separate our concerns along this line.

The basic UI components we need to fulfill our user functions have basically already been identified. Let’s pretend we already setup some basic UI components that can fulfill our requirements, reusing a library we perhaps already have, or quickly implementing the basic tools that the OS we are creating a Notes app for can supply us easily enough with what we need (we don’t need much beyond what most platforms offer by default).

Next we are going to hook up the UI components to code that does something. For this, we typically use the (view) controller pattern.

A Commanding Controller

A controller is the first layer between UI components and business logic. Basically, this is what the UI will call when you press a button, or where it can retrieve a list of things the UI wants to show in say a table. It can be specific for a specific UI client, but parts or all of it can sometimes also be shared among various different platforms.

One of the first thing we need in our example is something simple like:

NoteVM NotesUIController.CreateNote(string text)

Next, I will want to have a collection of Notes that I can point my List-like UI component to, to show all notes I want the user to see. Something like:

IObservableList<NoteVM> NotesUIController.DisplayNotes;

At the most basic of levels, we could now have a UI that consists of a textbox where we can enter the text of the note, a button that will create a Note with the text from the textbox, and a ListView that displays the contents of NotesUIController.DisplayNotes.

The logic in the controller now basically only has to initialize the controller with an empty DisplayNotes (observable) collection and then implement the CreateNote method. All this method has to do is create a Note viewmodel that is then added to the DisplayNotes collection. Here’s what a C# version looks like (which would be very similar in Angular):

   publicclassCommandBlogController

   {

       publicclassNoteViewModel

       {

           publicNoteViewModel(string text)

           {

               Text = text;

           }

           publicstring Text { get; } = "";

       }



       public ObservableCollection<NoteViewModel> DisplayNotes { get; set; } = new ObservableCollection<NoteViewModel>();



       publicvoidCreateNote(string text)

       {

           var newNote = new NoteViewModel(text);

           DisplayNotes.Add(newNote);

       }

   }

For testing the UI, we don’t need anything else – set this as a DataContext for your WPF form, hook up the controls and it works. We don’t need a REST API, we don’t need an ORM or Database, we just needed our UI controls and our controller that can be acceptance tested immediately, or prototyped to use different types of UI, platforms, etc., before deciding to stick with one or two for the remainder of the project. And should you need more complex data to display, or a default set of Notes to see what the list would look like with a bunch of Notes entered, you can easily write a function in your controller that creates a few example notes or even generates some randomly whenever the controller is brought into existence by the UI.

Getting ready to Command

Now when we do want to store our notes, we can start using the Command pattern. What the command pattern does, basically, is record a user action so it can be played back again somewhere else (or easily reverted, for undo/redo scenarios). In that sense, the command pattern can also be seen as the increasingly popular message / handler pattern that is often used in service bus setups (distributing messages to different software handlers) and event sourcing scenarios (storing these messages in a table and creating your objects by playing them back).

The first thing we will do in our example is create a command that contains all the information we need to process the command later. In our case, we have the type of action (a Create) and a set of parameters specific to this command (in this case the Note text). So our first version of the Command could look like this:

   publicclassCreateNoteCommand 

   {

       publicstring Text { get; set; }

   }

Note that this command basically looks like the function on our controller, but now the user action is encoded in a class with properties rather than a method with parameters as we saw on the controller.

Next, we need a way to create this command, and to keep track of these commands to do something with them later, such as send them to a backend, repository, etc. For this, we will create a new command controller class, like this:

   publicclassNoteCommandController : INoteCommandController

   {

       public ObservableCollection<CreateNoteCommand> Commands { get; } = new ObservableCollection<CreateNoteCommand>();

       public CreateNoteCommand Create(string text)

       {

           var command = new CreateNoteCommand { Text = text };

           Commands.Add(command);

           return command;

       }

   }

Now all we need to do is hook up our CommandController to our NotesController, and call it from the CreateNotes method. This is very straightforward. First, we will inject the NoteCommandsController into our NotesController like this:

       private INoteCommandsController _commandFactory;

       public NotesController(INoteCommandsController commandFactory)

       {

           _commandFactory = commandFactory;

       }

And then, we will create a new command whenever the CreateNote method is called on the controller, like this:

       publicvoidCreateNote(string text)

       {

           var newNote = new NoteViewModel(text);

           DisplayNotes.Add(newNote);

           _commandFactory.Create(text);

       }

Done! Now every time a user creates a new Note, a command will be created for this.

Let’s add some more functionality to our test program: the ability to delete a note. The steps we need here are simple: add a delete button somewhere with the note, then have that call a DeleteNote method on the controller, and generate a command for it.

We do, however, need a few more things here. First, we need to be able to identify which Note we are going to delete, so we need to add some kind of identifier (Id) to our Note that we can use to tell the controller what note to delete. This is easily done:

As you can see we added a Guid property (globally unique identifier) and had the NoteViewModel set it to a new one right upon creation, and prevented it from being able to change afterwards.

       publicclassNoteViewModel

       {

           publicNoteViewModel(string text)

           {

               Text = text;

               Guid = Guid.NewGuid();

           }

           publicstring Text { get; } = "";

           public Guid Guid { get; }

       }

Guids are a nice fit here because they can be created client side – no waiting for the database to provide you with an Id. That’s not to say you are required to use a Guid – all we need here is that the actions of the user can be identified as being about the same note. A very basic temporary id could be used for that as well that is then translated to a more permanent id later.

We will also hook that Guid up to our Commands, so if we have multiple commands, we know what Note they are about. Since we will have multiple commands, we will first setup an interface and a base class so that we can share some logic:   

   publicabstractclassNoteCommandBase : INoteCommand

   {

       public Guid NoteGuid { get; set; }

   }

   publicclassCreateNoteCommand : NoteCommandBase

   {

       publicstring Text { get; set; }

   }

Now we share our NoteGuid across all our NoteCommands using the abstract NoteCommandBase class, and we provide an INoteCommand interface for our collections and so on. Finally we will use this in our command collection:

   publicclassNoteCommandsController : INoteCommandsController

   {

       public ObservableCollection<INoteCommand> Commands { get; } = new ObservableCollection<INoteCommand>();

Now we can comfortably and quickly start implementing new functionality with command support. Let’s add our Delete and Update functions, first on the controller:

       publicvoidUpdateNote(Guid guid, string text)

       {

           var noteToUpdate = DisplayNotes.Single(w => w.Guid == guid);

           noteToUpdate.UpdateText(text);

           _commandFactory.Update(guid, text);

       }

       publicvoidDeleteNote(Guid guid)

       {

           var noteToDelete = DisplayNotes.Single(w => w.Guid == guid);

           DisplayNotes.Remove(noteToDelete);

           _commandFactory.Delete(noteToDelete.Guid);

       }

And then add them to the CommandFactory:

       publicvoidDelete(Guid guid)

       {

           var command = new DeleteNoteCommand { NoteGuid = guid };

           Commands.Add(command);

       }



       publicvoidUpdate(Guid guid, string text)

       {

           var command = new UpdateNoteCommand { NoteGuid = guid, Text = text };

           Commands.Add(command);

       }

Pretty straightforward. We are already recording the user’s actions and with minor modifications we can choose to play back against backend business logic: post them on busses, to back ends, local or remote repositories, show those actions in the ‘history/changes list’ of objects, and even undo them to return to a previous state. In fact, if you are playing along with this in a UI project (I will include add a GitHub example at the end), you can expose the command collection to a list / table view right now and you’ll have a view of your user’s history right there, which you can also filter by Guid for a selected object.

For this to happen, we first need to collect the commands in our controller and then offer a filtered collection of them that we can adjust depending on the selected Note:

       public ObservableCollection<INoteCommand> AllCommands { get; privateset; } = new ObservableCollection<INoteCommand>();

       public ObservableCollection<INoteCommand> DisplayCommands { get; privateset; } = new ObservableCollection<INoteCommand>();

Next, we will have the command factory return the created command so that we can add them to our new collections used for display:

       privatevoidAddCommand(INoteCommand noteCommand)

       {

           AllCommands.Insert(0, noteCommand);

           DisplayCommands.Insert(0, noteCommand);

       }

(Note that we use Insert so that new items show up on top. When using observable collections, this is more efficient then outright sorting.)

Then we call the new AddCommand with the returned command whenever we generate a command in the controller:

       var noteCommand = _commandFactory.Create(newNote.Guid, text);

       AddCommand(noteCommand);

Now, to have some fun, we can do some more accurate tracking of changes. If we hook up into the TextChanged command of a TextBox in WPF for instance, we can get updates on the exact changes that happened in a text and record those.

For instance, if we add this:

       privatevoidNoteEditText_TextChanged(object sender, TextChangedEventArgs e)

       {

           var note = GetNoteViewModel(sender);

           // only capture in edit mode

           if (note is NoteEditModel)

           {

               note = note as NoteEditModel;

               var textBox = sender as TextBox;

               var orgText = note.Text;

               note.Text = textBox.Text;

               vm.PostTextChanges(note, e.Changes, orgText);

           }

       }

And then this:

       publicvoidPostTextChanges(INoteViewModel note, ICollection<TextChange> changes, string orgText)

       {

           foreach (var change in changes)

           {

               if (change.RemovedLength > 0)

               {

                   var text = orgText.Substring(change.Offset, change.RemovedLength);

                   var command = _commandFactory.DeleteText(note.Guid, change.Offset, text);

                   AddCommand(command);

               }

               if (change.AddedLength > 0)

               {

                   var text = note.Text.Substring(change.Offset, change.AddedLength);

                   var command =_commandFactory.InsertText(note.Guid, change.Offset, text);

                   AddCommand(command);

               }

           }

       }

… as well as of course the two new InsertNoteText and DeleteNoteText commands, we can now keep track of the exact changes made to the note text in detail.

One additional advantage for us developers and UI designers, is that we now also can analyze how a program gets used – we don’t need expensive software to keep track of what our user does, as we already have this data ourselves. We can also store a set of user actions and play them back, setup specific test scenarios and so on, without having to implement complicated and hard to maintain UI testing software. Even when we do use those, now in many cases all we have to assert is that user actions resulted in the right commands.

What did this bring us so far?

Tracking user changes as commands gives you a great start for implementing your own Undo and Redo, as well as allowing you to test in far more detail and track what your users are doing (or were doing when that crash happened). While a few platforms natively support some Undo and Redo in specific controls, generally and certainly in the JavaScript community this is typically not available unless you implement a command like pattern. Some alternatives are picking up steam though, such as Redux, which preserves the whole controller’s state and considers it immutable, and allowing you to work with state trees that you can navigate to achieve your undo and redo, but it at times feels a bit overkill – typically just the commands are a fraction of the entire state, and you lose the fine-grained detail such as an edit history per object as we’ve seen here, as well as lose track of the intent of the user. To regain this, you’ll have to start comparing state changes and take it from there.

Another huge example and often cited as the main reason for switching to it in complex scenarios, is that as the UI increases in complexity, the command pattern scales completely linearly. Your user performed some actions, and those actions show up as commands. It matters little how much data your user is viewing and how much edit actions he or she can do, because in the end exactly and only those three actions that he or she performed are going to show up as commands and then sent to the backend, where the user intent is never lost. And you will see in the next blog how this helps immensely with processing, storing and event sourcing data in the backend. 

In the example project for this article, you will find a demonstration of playing back these commands in the UI. Currently there is only a WPF example, but I do intend to add an Angular 2.0 example later (we already used the pattern in an Angular 1.x project in an area where the ‘regular’ UI approach became too complex). And of course I will gladly accept pull requests with other UI implementations … ;)

I read your article and didn't understand why you named gave NoteCommandController this name. I would choose for NoteCommandFactory. Can you please explain why?

Like
Reply

To view or add a comment, sign in

More articles by Arwin van Arum

  • I, Test with Mocks and Builders

    Building and testing with Mocks and Builders Any code for this blog can be found here:…

  • I, DATETIMEPROVIDER

    The Persistence of Memory, by Salvador Dali There are several things I learnt coming out of a large project, and before…

    1 Comment
  • I, REPOSITORY

    The repository pattern — used by most programmers at some point in their career (wittingly or unwittingly), but very…

    1 Comment
  • I, SHARED PROJECTS

    “n-dependent vs in-dependent” There’s a long history in programming of having trouble with dependencies. Probably the…

Explore content categories