[C# Anti-Pattern] Procedural code in Object-Oriented code

The previous articles/videos have been on design patterns – good ways to solve common programming problems. This article/video will cover an anti-pattern – a bad way that programs are sometimes written. I’ll show you how to detect the anti-pattern, and how to fix it.

I call this anti-pattern “Procedural code in Object-Oriented code “.

 

Watch the video version here:

 

What it is

Procedural code is code that must run in a specific order.

Think of it like driving directions: Go to the third streetlight, turn right, drive 10 blocks, turn left, then turn right after the second stop sign. If you don’t follow all those steps, in the exact order they were given, you probably won’t arrive at your destination.

The same problem can happen in a program – the code is written so steps must be performed in a specific order. If the programmer forgets to include a step, or calls one out of order, the program may not produce the correct results.

 

How to eliminate this anti-pattern

To prevent this problem, object-oriented programming uses information hiding and encapsulation.

I’ll demonstrate how to convert procedural code to good OOP code, using a sample order entry program.

We’ll have a Customer class, which only has the customer ID, and a Boolean property, showing if the Customer is a Premium member. Premium members don’t pay shipping for their orders.

The Order class will hold the Customer and a list of LineItem objects.

The LineItem class holds an InventoryItem object in the order – its description, price, weight – and the quantity ordered.

Order.cs

Customer.cs

LineItem.cs

InventoryItem.cs

After all the items are added to an order, the programmer needs to determine the total cost of the order. The total includes tax, and shipping (if the customer is not a “Premium” member).

Here is how it might be done, using procedural code:

TestPlacingOrders.cs

In the procedural example, the programmer calculates the subtotal, tax, shipping, and total – as local variables.

Notice that all the calculation logic is all done at the highest level of the class hierarchy.

This works correctly, but could lead to problems in the future.

You might decide to make a mobile app version of your program, so customers can place orders from their phones. If your company hires a new mobile app developer, and they look at the Order class, they won’t know the rules, and sequence, for calculating the order totals.

Or, you might start selling to customers in a different country. Those orders might not have tax applied, and might have a higher shipping cost. With this procedural code, you would need to find every place where the order totals are calculated and make changes for the new rules. It’s easy to miss one.

With a small sample like this, it’s not too difficult to find the place where the Total is being calculated. But, when your solutions have dozens of projects, and hundreds of thousands of lines of code, this becomes a serious problem.

 

How to detect this anti-pattern

One way is too look for any place in your code where a variable, or property, is being assigned a value – and all the properties to compute that value (the ones on the right side of the “=” sign), are from another class. Another place where you might see this anti-pattern is in large “if-else”, or “switch” statements.

When you see this, you can probably move those calculations into get-only properties, of the other class.

Here is what the code looks like after refactoring.

Order.cs

Customer.cs

LineItem.cs

InventoryItem.cs

TestPlacingOrders.cs

In this version of the code, the calculation logic is moved “down” the hierarchy, and the results are “pulled up”.

DependenciesUp

If a new programmer looks at this code, and wants to see how the Total is calculated, the logic is much more obvious.

 

Where I’ve found it useful

I usually see this anti-pattern in large programs, that have been worked on by many programmers, or many years.

Code gets copied and pasted throughout the program. When a change to the rules happens, it doesn’t always get updated every place where the code was copied. When you find these differences, you’ll often hear that it’s a known problem – but it only happens in certain situations, so no one has ever investigated the root problem.

By fixing this anti-pattern, your programs will be more reliable, since it’s using the same rules everyplace. It will also be easier and faster to modify your programs. You’ll only need to make the change in one place.

Leave a Reply

Your email address will not be published. Required fields are marked *