Translated to our world of software, the good genes theory means the absence of special cases. Beautiful code has a consistent level of expression. Just as deviations from the mathematical averageness makes a face less attractive, so does any coding construct that deviates from the main style of your application.
These constructs signal bad genes in our programs because they make it harder to form a mental model of the program. That’s just the way your brain works; when presented with inconsistencies and conflicting representations, your brain selects one of the stimuli at the price of the other. You can switch between them, but it’s going to be expensive.
That means as soon as you break the expectations of someone reading your code, you’ve introduced a cognitive cost. This is a cost that makes your programs harder to understand and riskier to modify. Broken expectations are to blame for many bugs.
Attractive Criminals | |
|---|---|
|
|
Criminals benefit from beauty, too. There’s a growing body of research on the topic. The research indicates that attractive defendants are perceived as less guilty and, should they be convicted, receive a more lenient sentence than unattractive offenders. And it’s a finding that seems to hold for both mock jurors, used during experiments, and real-life judges (source: The Psychology of Physical Attraction [SF08]). These findings are, of course, worrisome. But sometimes the attractiveness of offenders works against them. A good-looking criminal may receive a more lenient sentence for a burglary. But if the criminal used his good looks to swindle his victims, we penalize his success. If you’ve ever doubted the importance of beautiful code, you now see how profound attractiveness is in our lives. |
The beauty principle applies to software architectures, too. Since an architectural decision is by definition more important than a local coding construct, breaking beauty in a high-level design is even worse.
Consider a codebase that has multiple ways to do interprocess communication, differs in its error-handling policies, or uses several conflicting mechanisms for data access without any obvious benefit. Such a system is hard to learn and work with—particularly since the knowledge you build up when working with one part of the codebase doesn’t necessarily transfer to others. Here’s what we can do to prevent it.