For this kind issues Martin Fowler proposed Specification pattern:
...design pattern, whereby business rules can be recombined by chaining the business rules together using boolean logic.
A specification pattern outlines a business rule that is combinable with other business rules. In this pattern, a unit of business logic inherits its functionality from the abstract aggregate Composite Specification class. The Composite Specification class has one function called IsSatisfiedBy that returns a boolean value. After instantiation, the specification is "chained" with other specifications, making new specifications easily maintainable, yet highly customizable business logic. Furthermore upon instantiation the business logic may, through method invocation or inversion of control, have its state altered in order to become a delegate of other classes such as a persistence repository...
Above sounds a bit high-brow (at least to me), but when I tried it in my code it went quite smoothly and turned out easy to implement and read.
The way I see it, main idea is to "extract" code that does the checks into dedicated method(s) / objects.
With your netWorth
example, this could look about as follows:
int netWorth(Person* person) {
if (isSatisfiedBySpec(person)) {
return person->assets - person->liabilities;
}
log("person doesn't satisfy spec");
return -1;
}
#define BOOLEAN int // assuming C here
BOOLEAN isSatisfiedBySpec(Person* person) {
return Person != NULL
&& person->isAlive
&& person->assets != -1
&& person->liabilities != -1;
}
Your case appears rather simple so that all the checks look OK to fit in a plain list within a single method. I often have to split to more methods to make it read better.
I also typically group / extract "spec" related methods in a dedicated object, although your case looks OK without that.
// ...
Specification s, *spec = initialize(s, person);
if (spec->isSatisfied()) {
return person->assets - person->liabilities;
}
log("person doesn't satisfy spec");
return -1;
// ...
This question at Stack Overflow recommends a few links in addition to one mentioned above:
Specification Pattern Example. In particular, answers suggest Dimecasts 'Learning the Specification pattern' for a walkthrough of an example and mention "Specifications" paper authored by Eric Evans and Martin Fowler.