Engineer Good Citizen Data Services

Photo by gotafli on Unsplash

 

What’s wrong with this business logic code?

Note that the data service CustomerDataSource is part of the same codebase.

  var customers = CustomerDataSource.Search(criteria);
  if (customers != null && !customers.Any())
  {
     foreach (var customer in customers)
     {
        if (customer != null && !customer.Deleted)
        {
           // .. do something useful with this valid customer.
        }
     }
  }

So, what is the problem? 

Simply this: CustomerDataSource.Search(criteria) is not doing its job—it returns terrible data.

Terrible data? How do you mean?

  1. Firstly, CustomerDataSource.Search(criteria) might return a null collection. Third-party code will require null checks for collection return values, but our code should never return a null collection. We are being careless when we return null values for collections. Let’s return an empty collection instead. At least we can call methods on an empty collection. Calling a method on a null will result in a NullReferenceException.
  2. Secondly, we can infer from the null check on the customer reference that individual elements in the customers collection can be nulls. We have no assurance that we receive only proper customer objects.
  3. Lastly, here in our business logic, we also must explicitly exclude deleted customer instances. It’s unlikely that we use deleted customers in many business contexts! So what are they doing here?

So,

    What intelligent work is CustomerDataSource.Search(criteria) performing?  

It’s a fair question. Search() seems to be retrieving some data and then passing it on—mindlessly. It appears that the authors of Search() applied little thought to how to filter the returned data for the caller. There is a distinct lack of engineering. A return value should be immediately consumable without further need for basic processing for common data problems, like nulls and obviously invalid states.

And it comes down to realising that the responsibility of producing decent, consumable data happens as close to the data source as possible. It means that callers further up the chain don’t have to do the work. Software engineers realise this and put the data cleansing logic with the service that gets the data. That’s what engineers do. And if we don’t do that, then we are not so much Software Engineers but rather mere software writers.

0 replies

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply