Simplify Boolean Expressions

 class​ SpaceShip {
 
  Crew crew;
  FuelTank fuelTank;
  Hull hull;
  Navigator navigator;
  OxygenTank oxygenTank;
 
 boolean​ willCrewSurvive() {
»return​ hull.holes == 0 &&
  fuelTank.fuel >= navigator.requiredFuelToEarth() &&
  oxygenTank.lastsFor(crew.size) > navigator.timeToEarth();
  }
 }

Boolean expressions that combine multiple conditions are often hard to understand and easy to get wrong. But you can make them easier with a few simple tricks.

As in the previous comparison, you can see an example of a validation method. The condition is more complex than the previous one, but it’s already condensed in a single return statement according to Return Boolean Expressions Directly.

The sheer size of the condition makes it hard to understand. It spans over several lines of code and combines checks from five different objects. Due to its size, it’s easy to introduce a fault when you have to change a part of it. But even before changing it, you’ll probably spend valuable programming time to grasp its meaning.

When you have to combine several conditions into a single check, it’s better to group them in some way. A good grouping depends on the semantics of the condition, and you can try to group by topics or level of abstractions.

Within a method, you should combine statements that are on a similar level of abstraction. Ideally, a higher-level method should call methods of the next lower level.

Here, the method willCrewSurvive() verifies each low-level detail in the same condition. Can you think of a level of abstraction in between? How about this:

 class​ SpaceShip {
 
  Crew crew;
  FuelTank fuelTank;
  Hull hull;
  Navigator navigator;
  OxygenTank oxygenTank;
 
 boolean​ willCrewSurvive() {
 boolean​ hasEnoughResources = hasEnoughFuel() && hasEnoughOxygen();
»return​ hull.isIntact() && hasEnoughResources;
  }
 
»private​ ​boolean​ hasEnoughOxygen() {
 return​ oxygenTank.lastsFor(crew.size) > navigator.timeToEarth();
  }
 
»private​ ​boolean​ hasEnoughFuel() {
 return​ fuelTank.fuel >= navigator.requiredFuelToEarth();
  }
 }

Wow, a lot has changed here! The willCrewSurvive() method is still present, but now it calls other methods and aggregates their return values.

First, we have added a boolean variable that bundles similar aspects together by their topic: depletable resources. We also gave it a meaningful name, hasEnoughResources. The variable combines the results of two method calls, hasEnoughOxygen() and hasEnoughFuel(). You’ll find the actual details of the conditions inside these two methods.

Next, we’ve combined the variable hasEnoughResources with the last missing piece of the original condition, hull.holes == 0. We, however, use the method hull.isIntact() from the Hull class instead. It already has a meaningful name so there’s no real reason to store it in another boolean variable.

Although there are more lines of code now, we’ve improved the understandability of the code a lot. You no longer need to grasp one large condition at once. Thanks to the grouping, you can do it step by step. Plus, the names of variables and methods communicate the intended result. Each method on its own is simple and comprehensible at one glance.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.117.7.131