In defensive programming, guard clauses are used to protect your methods from invalid parameters. In design by contract, guard clauses are known as preconditions, and in domain driven design, we use them to protect invariants — unbreakable rules that form assumptions about our model:
public class BankAccount{ private int balance; public void WithDraw(int amount) { if (amount < 0) throw new InvalidAmountException( "Amount to be withdrawn must be positive."); if ((balance - amount) < 0) { string message = String.Format( "Cannot withdrawpublic class BankAccount{ private int balance; public void WithDraw(int amount) { if (amount < 0) throw new InvalidAmountException( "Amount to be withdrawn must be positive."); if ((balance - amount) < 0) { string message = String.Format( "Cannot withdraw ${0}, balance is only ${1}.", amount, balance); throw new InsufficientFundsException(message); } balance -= amount; }}, balance is only .", amount, balance); throw new InsufficientFundsException(message); } balance -= amount; }}
Unfortunately, in examples like this, the true intention of the method – actually withdrawing money – is now lost in a forest of error-checking guard clauses and exception messages. In fact, the successful path — representing 99% of executions (when there is enough money) — only accounts for 1 line in this method. So let’s refactor:
public class BankAccount{ private int balance; public void WithDraw(int amount) { ErrorIfInvalidAmount(amount); ErrorIfInsufficientFunds(amount); balance -= amount; } ...}
By extracting these guard clauses into separate guard methods, the intention of the method becomes much clearer, and the explicit method names give a clear indication of what is being checked inside (regardless of how those checks are implemented). And we can concentrate on the main success path again.