Conditional Logic and Decision Making
The Guardian Pattern strategically places a guard condition before a risky operation in an 'and' expression to prevent runtime errors.
Why Order Matters
A logical expression can do more than produce a final true or false result. The order of its conditions can determine whether a later operation runs at all. The Guardian Pattern takes advantage of this behavior by placing a safe guard condition before an operation that could cause a runtime error.
What do you think happens?
Suppose an and expression checks a guard first, and that guard is false. What happens to the risky operation that comes after it?
Reveal answer
Answer: The risky operation is skipped
Short-circuit evaluation stops the expression as soon as a condition is false, so subsequent operations do not run.
Following a Guarded Expression
The Guardian Pattern has two parts. First comes the guard: a condition that checks whether it is safe to continue. After the guard comes the risky operation: an operation that should run only when the guard succeeds. In an and expression, a false guard stops evaluation before the risky operation is reached.
Checking a Denominator Before a Calculation
A calculation should use a denominator only when the denominator is non-zero. Which condition must come first in the guarded and expression?
Identify the guard: The non-zero check is the guard because it determines whether the denominator is safe to use.
Identify the risky operation: The calculation using the denominator is the risky operation because it should not run when the denominator is zero.
Order the conditions: Place the non-zero guard before the calculation in the and expression.
Apply short-circuit evaluation: When the guard is false, the expression stops and the calculation is not evaluated.
The non-zero denominator check protects the calculation only when it appears before the calculation.
Building the Safe Order
To construct a guarded and expression, first identify what could cause a runtime error. Then identify the condition that proves the operation is safe. Place that guard before the risky operation. The guard must be evaluated early enough to stop the expression before the risky operation is reached.
| Potentially risky use | Guard to place first |
|---|---|
| Using a denominator in a calculation | Check that the denominator is non-zero |
| Using an array index | Check that the index is valid |
| Using a data value | Check that the data value is valid |
Common guard-and-operation relationships
When Protection Fails
An incorrectly ordered expression evaluates the risky operation before it reaches the guard. If that operation encounters an unsafe value, the runtime error can occur before the guard has any chance to stop evaluation. The same guard may be present, but its position makes it ineffective.
Putting the guard after the risky operation
Short-circuit evaluation can stop only operations that have not yet been reached. It cannot undo an operation that already ran.
Fix:
Move the safety check before the calculation.Treating the presence of a guard as enough
The guard does not protect an earlier operation.
Fix:
Review the evaluation order, not just the conditions that appear in the expression.Ignoring the specific unsafe input
The risky operation can run with an unsafe denominator before any protection is applied.
Fix:
Match the guard to the risk and place the non-zero check first.
Guard Construction Practice
For each situation, identify the guard and the risky operation. Then state which one must appear first in an and expression: a denominator that must not be zero, an array index that must be valid, and a data value that must be valid.
Hints
- The guard states the condition that makes the later operation safe.
- The risky operation is the use of the value, index, or denominator.
- The guard must come first so a false result can stop evaluation.
- Name the operation that could produce a runtime error.
- State the condition that makes that operation safe.
- Place the guard before the risky operation in the and expression.
- Check the false-guard path: the expression should stop before the risky operation runs.
- Check the true-guard path: the expression may continue to the risky operation.
Key Takeaways
- The Guardian Pattern places a guard condition before a risky operation in an and expression.
- Short-circuit evaluation stops the expression when a condition is false.
- A guard can prevent a later operation from running only when the guard comes first.
- Common guards check denominators, array indices, and data values before those values are used.
- Incorrect ordering can allow a runtime error before the guard is evaluated.
Key Takeaways
- Use a guard condition to establish that a risky operation is safe.
- Place the guard before the risky operation in an and expression.
- Rely on short-circuit evaluation to stop when the guard is false.
- Remember that a guard placed after the risky operation cannot protect it.