BT

The Dangers of If Statements in Domain Logic

| by Jan Stenberg Follow 28 Followers on Feb 10, 2017. Estimated reading time: 3 minutes |

A note to our readers: You asked so we have developed a set of features that allow you to reduce the noise: you can get email and web notifications for topics you are interested in. Learn more about our new features.

The if statement found in most programming languages has two major roles; validating input to protect the domain from erroneous data, and for dealing with business logic inside the domain. Unfortunately, we spend too little time managing the risks of using if statements in logic from a business or domain perspective, Udi Dahan claimed in his presentation at the recent DDD Europe Conference in Amsterdam.

When buying things online, we look at different items and read details about some of them. When we find something to buy and add that to the shopping cart we also move from the query side to the command side of the interaction. One of the important questions Dahan thinks we should ask for any kind of command, is what would cause the command to fail, and emphasizes that we must distinguish technical failures, like a crashed web server or some deserialization error, which should be handled by infrastructure, from logical failures, like adding an item to a shopping basket just after the same item has been deleted from the product catalogue.

Checking if something is deleted is an example that often comes up in Dahan’s work with customers. For him, one step in dealing with problems like deleted items is to make a distinction between private and public data, and compares with a content management system where you edit pages and content, and finally make the information public by pressing a Publish button. On the private side, a user can add an item, update or delete it without any problem, and finally when satisfied make it public.

On the public side, we need to replace deletes and checks for deletion with more business centric logic; we have to think more about why an item should be deleted. An example is a product that is not for sale anymore; then maybe a better way is to create a specific command that will mark the product as not for sale, instead of using some form of soft or real delete.

One potential problem with such a solution is the race condition where a customer adds an item to the shopping basket just before the same item is flagged as not for sale. Later when the customer wants to check out the basket, it’s not possible to buy that item anymore. Looking at the problem in this way is, for Dahan, a very narrow data-centric point-in-time perspective; instead he describes the problem as a typical scenario with multiple actors working on the same object at the same time.

In a collaborative domain, with multiple actors operating on the same data in parallel, Dahan thinks we should start thinking about CQRS. When applying CQRS to a domain, his recommendation is to make it as simple as possible and design the solution so that a command that has been validated and enters the domain logic almost never fails. This means that when handling a command, we must for instance be prepared to lose in a race condition and still fulfil the overall business objectives. Often this leads to eventual consistency, but not the technical type with a read model that eventually becomes in sync with a write model; instead it’s from a business perspective. In this example, it’s about customers adding an item to their basket that is not for sale.

One solution to this is to use a long-running process that behind the scene removes the item not for sale from shopping baskets as they become inactive or time out. Eventually the item has been removed from all baskets and thus not sold anymore.

When looking into a system, we probably find many other if statements that checks for state in some form and for each of them we should ask ourselves if there are other actors that may change the same state. This way we can find potential collaborations and needs for a long-running process. Dahan notes though that we must be aware of using too many long-running processes, and emphasizes that it’s not a silver bullet.

Rate this Article

Adoption Stage
Style

Hello stranger!

You need to Register an InfoQ account or or login to post comments. But there's so much more behind being registered.

Get the most out of the InfoQ experience.

Tell us what you think

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

Re: "If Statements" is too broad by Jan Stenberg

Specifially Udi talked about if statements dealing with state in a domain that may be changed by concurrent actors.
In my experience that's quite a common case; two users, or a user and a background process, that is working on the same entity or aggregate.

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

3 Discuss

Login to InfoQ to interact with what matters most to you.


Recover your password...

Follow

Follow your favorite topics and editors

Quick overview of most important highlights in the industry and on the site.

Like

More signal, less noise

Build your own feed by choosing topics you want to read about and editors you want to hear from.

Notifications

Stay up-to-date

Set up your notifications and don't miss out on content that matters to you

BT