Sponsor: Do you build complex software systems? See how NServiceBus makes it easier to design, build, and manage software systems that use message queues to achieve loose coupling. Get started for free.
Moving from CRUD (Create, Read, Update Delete) based UI to a Task Based UI means creating a user interface that makes users’ tasks explicit. Tasks (or actions, commands) are a way to guide a user into the specific actions they can take for a given state or workflow. When you break down by actions, you then can start seeing where the boundaries might lie, which can help split entities into multiple boundaries.
Check out my YouTube channel where I post all kinds of content that accompanies my posts including this video showing everything that is in this post.
For this example, I’m using an Product Entity that contains various properties used in our application.
All the properties should be self-explanatory. If we were creating a CRUD-based UI, we would simply have a page/form that allows the user to set all the various properties.
When you click the save button, all the data is sent to the server and the entire entity is updated.
So what’s the problem with CRUD?
In some situations, there may not be anything wrong with creating CRUD-based UIs. However, when you start to infer the intent of the users based on what data they are changing is when you’re better off moving to a Task Based UI.
In the CRUD-based UI from above, if a user were to change the price from $85 to $80, then click save, did they just change the price? Was that their intent? Or was their intent to do a price decrease? What other parts of your system need to be aware of that occurring?
Could you notify customers that had that product in their “Wishlist” that the price is now lower?
CRUD Based UIs do not capture the intent of the user. It’s not explicit. You need to derive what the user intent was. In a Task-Based UI, you’re making the users’ actions explicit. Make the implicit explicit.
The first step to building a task-based UI is understanding which properties on your entity change together or are related
The red (top) box that has the Name and Description could be changed together, or independently. These two likely don’t have much behavior/tasks behind them so they could just be CRUD.
The purple (lower left) box with Price, For Sale, and Free Shipping are likely for sales purposes.
The green (lower middle) box has the Cost and this is for the Cost from the Vendor or Manufacturer. It does not relate at all to the Sale price.
The yellow (lower right) box has the Quantity which is the Quantity on Hand in the warehouse. It does not relate to the cost or the sale price.
Task Based UI
If you take the CRUD Based UI and separate each box into its own boundary, you then can start asking the question, what is the intent of users when they are changing these fields. Why are they changing them? It’s likely different users/roles have an interest in different pieces of data.
The SKU, Name, Description might be owned by the Catalog service/boundary. This may be totally CRUD in nature. However, the Price might be owned by Sales. Purchasing would own the Cost and the Quantity on Hand would be owned by the Warehouse.
From a user/role perspective, what tasks are they trying to perform when they want to change data within that boundary.
We can see now that Sales you can IncreasePrice or DecreasePrice. If we wanted to increase the Price, we would provide the ability for that specific task/command.
If the warehouse did a stock count of a product and determined there weren’t as many on the shelves as what the system says, they would be doing an Inventory Adjustment. They aren’t just updating the QuantityOnHand value, they are explicitly changing the quantity to add or remove from the QuantityOnHand for a specific reason.
Not only have we defined explicitly what users’ tasks/actions are, but we’ve defined boundaries. The concept of a product could live within multiple boundaries/services. You do not need to have an entity live in one single place and it contains all the data for the entire system.
Additional Related Posts
Developer-level members of my CodeOpinion YouTube channel get access to the full source in this post available in a git repo. Check out the membership for more info.