My previous blog post reminded me a refactoring that I did on one of my previous projects (in AX 2012).

I needed to adjust a piece of logic and found that it’s implemented as a method with more than two thousand lines. Of course, nobody could understand what’s going on there. Such code in unmaintainable.

After exploring it and comparing parts of the method, I realized that it consists of many almost identical blocks of code. There where select statements with slightly different conditions, otherwise the code was the same. The developer clearly didn’t know how to write the queries dynamically and also didn’t think about extracting the remaining code to a method to be called from each place. When he needed a new condition, he put the current method body to an if block, duplicated the whole method body in the else block and changed a few things in where clauses.

Because no one could understand the method, there were even two more copies of the whole method, when someone needed a slightly different behavior and didn’t dare to adjust this enormous method for another scenario.

The logic was somewhat similar to what I described in my previous blog post. We ran a specific query to find some data and tried to do something with it. If it didn’t give us the expected result, we tried a slightly more generic query and then even a more generic one, and so on. You can imagine it as finding a discount for a particular customer and item, then trying to find it for an item and a group of customers etc. (The real scenario isn’t important and I don’t even remember it well anymore.)

What I did was extracting the logic to a method that took a query as a parameter. Then I created a collection of Query objects and executed them one by one, always checking the result.

The queries were created by methods, each with a name describing the business scenario. Therefore the code creating the list of queries looked like this:

add(this.findByItemAndCustomer());
add(this.findByItemAndCustGroup());
add(this.findByItemOnly());
... approximately ten queries in total ...

Then I easily added my logic and I asked a business consultant to verify that we have the right set of rules and we execute them in the right order. Although he wasn’t familiar with X++, he was pleasantly suprised to learn that he actually could read the code and understand what it does – and therefore review whether it meets business requirements.

So… we got from a method that even no developer could make sense of, to something that even non-programmers can understand.