Break down complex conditions

Summary

Businesses often have complex rules. That can lead to code that is complicated, and hard to read. Use boolean variables for individual conditions. Your code will be easier to think about.

Situation

You have to program some complex business rules.

Action

Define boolean variables for conditions:

  • $isFewKids = ($kids > 0 && $kids <= 3);

Use them in ifs:

  • if ($isFewKids && ! $isNearWater && ! $isNearRoad) {
  •     $rating = 4;
  • }
Explanation

Businesses often have complex rules. Here's an example for a goat insurance agency. They give each goat household a risk rating. You want to write a program to compute the rating.

Ol' Jo

You talk to Ol' Jo, who knows the rules better than anyone. Here's part of the interview.

Well, let's see. (Spits) Ratin's depend on how many kids they's got, and whether they're near water, or a road. 'Cause them kids, some are dumber than a box o' rocks.

If'n they ain't got no kids, they get a ratin' o' two. Ask me, which'n you didn't, they's the smart ones.

If they gots a few kids, like up ta three, well, it depends. If they ain't near a road, that means inside 50 meters, or at it, and they ain't near water, meanin' 100 meters or closer, they gets a ratin' of four. If'n they ain't near a road, but is near water, they gets a six.

Let's leave the interview there, and write ifs for what we have so far. Here's one way to do it.

  • $rating = 'Unknown - call Jade';
  • if ($kids == 0) {
  •     $rating = 2;
  • }
  • if ($kids > 0 && $kids <= 3 && $waterDistance > 100 && $roadDistance > 50) {
  •     $rating = 4;
  • }
  • if ($kids > 0 && $kids <= 3 && $waterDistance <= 100 && $roadDistance > 50) {
  •     $rating = 6;
  • }

That would work, but I wouldn't do it like that. Here's what I'd do.

  • $isNoKids = ($kids == 0);
  • $isFewKids = ($kids > 0 && $kids <= 3);
  • $isManyKids = ($kids > 3);
  • $isNearWater = ($waterDistance <= 100);
  • $isNearRoad = ($roadDistance <= 50);
  •  
  • $rating = 'Unknown - call Jade';
  • if ($isNoKids) {
  •     $rating = 2;
  • }
  • if ($isFewKids && ! $isNearWater && ! $isNearRoad) {
  •     $rating = 4;
  • }
  • if ($isFewKids && $isNearWater && ! $isNearRoad) {
  •     $rating = 6;
  • }

I've taken conditions like $kids > 0 && $kids <= 3, and made variables for them. That condition I've called $isFewKids. The translation between the business rules and the ifs is clearer. Errors will be easier to see.

Suppose you wanted Ol' Jo to check the code. This...

  • if ($kids > 0 && $kids <= 3 && $waterDistance > 100 && $roadDistance > 50) {
  •     $rating = 4;
  • }

... would give him a conniption. This...

  • if ($isFewKids && ! $isNearWater && ! $isNearRoad) {
  •     $rating = 4;
  • }

... he could understand, with a bit of coaching.

Adela
Adela

This is brain complexity stuff, isn't it?

Right! Breaking down complex conditions with boolean variables makes the code easier to think about. The load is less, and mistakes are less likely.

Where referenced