Manual reviews versus fitness functions
The chapter is about architecture governance, and the authors start with the tooling: design principles, good practices, and practices best avoided. Manual reviews and boards are marked red on their diagram, fitness functions green — checks that hold the chosen architecture characteristics automatically or semi-automatically. The hosts soften the verdict at once: the authors admit the "bad" practices appeared evolutionarily — first everything was truly bad, then CI and version control arrived, and one bad spot split into several less bad ones that can also be automated. One of the participants adds the story of the editions: while introducing the term "evolutionary architecture", the first version's authors forgot that governance had existed before them, and the second edition closes that gap. His argument: manual approaches scale poorly if you want to ship changes almost a thousand times a day, whereas a fitness function scales when it is unambiguously green or red and a machine, not a person, acts on the result.
Another participant came away from the chapter with a sense of relentless regulation: tighten this, inspect that, fail the build here. Yet at the end the authors warn against becoming a rigid regulator holed up in an ivory tower away from developers — log, watch, analyse, and then review the fitness functions themselves along with their reports. What emerges is a flexible instrument: constrain some things hard, elsewhere simply gather analytics and look for places to improve. The hosts then lay out the route through the chapter — examples sorted by the code, application and enterprise scopes, metrics, ready-made tools, a separate sub-chapter on chaos engineering, checklists and documentation. Hence the phrasing the host credits to Vova: a fitness function is closer to a checklist than to a whip that forces people to follow the rules.
The main sequence and cyclomatic complexity
At the code level the authors again reach for afferent and efferent coupling — incoming and outgoing links — though in the neighbouring book they themselves criticised the terminology for the one-letter difference that makes everyone confuse the direction. Then come abstractness, instability and the distance from the main sequence, the line where the two stay in the right proportion; that model's foundation, a participant recalls, was laid by Uncle Bob. Tilting towards abstraction gives the zone of uselessness, where any small change means writing a pile of infrastructure code; tilting towards implementation gives the zone of pain, where by the authors' formulas code with many complex methods and classes lands — a framework core, the participant supposes. A digression follows on where the metaphor comes from: on the astronomical diagram stars line up by luminosity and surface temperature, with short-lived giants ending as supernovae at the top right, dense white dwarfs below, and ordinary stars like the Sun on the main sequence. Astronomy has no zone of uselessness: it is supernovae that scatter matter with high atomic numbers, the stuff our own planet is made of.
The second metric is cyclomatic complexity: ten is the popular threshold, but the authors advise keeping to five. One of the hosts recalls a developer for whom seven hundred lines of C in a row were normal — at least you read it in one place — and admits he resisted the metric on algorithms himself: a complex, near-mathematical algorithm chopped into small methods sometimes reads worse, and the authors, by his account, later say the same, whereas shuffling structures and branching business logic are worth splitting up. Six months ago he argued with an engineer optimising a hitmap in a Russian social network: composition into functions and classes does not work for such tasks, the engineer insisted, and to the offer to refactor his code he sent back a seven-thousand-line function with global variables — there was nothing to answer, and policing complexity in such a module is pointless. Another participant is reading a book on how we read code: reading takes some sixty per cent of the time, and if the branches do not fit in working memory the logic cannot be followed.
From ArchUnit to the Netflix monkeys
Among ready-made tools the authors work through ArchUnit and, as the hosts feel it, plainly advertise it: control of package dependencies, naming rules such as a mandatory Controller suffix, annotation checks — the entity manager may only be touched inside transactional methods — and the classic layer control in both directions. Hence the joke that everyone without Java will now go and install it: the tools in books like this are somehow always Java. The authors point out you probably use something similar already — your language's linters with their APIs for custom rules, SonarQube, and, more specifically, license control for libraries through Black Duck; static analysis in modern IDEs is the host's own addition. Above the code level no ready-made tool exists: services are written in different languages, so the authors propose a two-step scheme — first teach everyone to log interactions in a single format, then analyse those logs with a Python or Ruby script. One of the hosts recognises an in-house tool where logs and metrics are pooled and joint queries are written over them.
Another participant adds that an orchestrator solves the same thing with network policies, and Dima that fitness functions move up to the development platform, which hides complexity behind a facade — as long as the abstraction does not leak. From chaos engineering they mention the Netflix monkey army and Chaos Kong, simulating the loss of an entire zone: thanks to such scenarios Netflix survived a zone going down at Amazon. Platforms are barely developed at the enterprise level, but the Frozen Caveman antipattern is named — an architect detached from the details who pushes practices popular a decade ago, like the character in the neighbouring book who kept asking what happens if we lose Italy. Documenting fitness functions in Cucumber, as the authors suggest, strikes the participants as odd; they recall Knuth's never-popular approach of mixing natural language with code, and its modern equivalent, Jupyter notebooks. Dima shows his own tool: a rule is described declaratively, with an owner and a check of whether it applies to the repository, and what a team usually needs to police is not complexity but the Node version and the package manager. The book's closing image is a guardrail on a road you should not drive off.
What to take away
- 01Manual reviews and boards do work, but they do not scale to the desired release frequency; the value of a fitness function is that a machine, not a person, acts on its result.
- 02Abstractness and instability set two traps: the zone of uselessness, where everything drowns in universal code, and the zone of pain, where complex methods and classes break at a touch.
- 03The cyclomatic threshold is the popular ten against the authors' five, yet in a seven-thousand-line function with global variables the metric is already meaningless.
- 04The higher the level, the fewer ready-made tools: instead of ArchUnit there is a single log format for service interactions, network policies in the orchestrator, and rules at the platform level.