One suggestion for mitigating sequential coupling.
I'm becoming allergic to code like this:
start_service()
run_tests()
or this:
check_validity(inputs)
do_actions(inputs)
These are examples of sequential coupling, a famous anti-pattern. Sequential coupling means that two procedures have to be called in a particular order or they don't work.
While you can find a lot of text about why sequential coupling is bad, there isn't a lot of advice on how to fix it. A lot of "fixes" boil down to having procedures check their own preconditions and do their own setup. But that just kicks the can down the road, moving the sequential coupling from one place to another.
Ultimately, sequential coupling is inevitable. Some procedures simply have to be called before other ones!
A good way to mitigate sequential coupling is to use dataflow to capture the precondition in code rather than just in documentation. Dataflow refers to definitions and uses of variables in your program.
For instance, we could improve the initial examples by writing:
service = start_service()
run_tests(service)
or:
checked_inputs = check_validity(inputs)
do_actions(checked_inputs)
In both cases the program dataflow makes it obvious that the first procedure does something the second procedure needs.
In typed languages we can do even better:
class CheckedString {
static void check(String input) {
// ...
}
String value;
CheckedString(String v) {
check(v);
this.value = v;
}
String toString() {
return this.value;
}
}
CheckedString
is a class with an object invariant: its value
is always one that passed the check
procedure. There is no way to construct a CheckedString
that has an unchecked value
.
Using dataflow and types, we can force callers to do checks before calling certain methods:
void act(CheckedString input) {
// ...
}
Making the precondition part of the dataflow and type of the procedure makes the whole program clearer and safer. It does not remove the sequential coupling, but it makes the preconditions obvious and easy to verify.
If you like this idea, you'll love dependent types.