Skip to content
back to the episode
Episode summary2023Fellow

Building Evolutionary Architectures — Episode 3

The club carries on with Building Evolutionary Architectures, opening the book's second part in its third stream. The hosts — Alexander, Vova and colleagues — bring in guest Sergey Baranov, and the conversation runs from fitness functions and genetic algorithms to an argument about connascence, the quantum that swallows the broker, and reuse as organ transplantation.

Code of Architecture · Book Club9 min read

This summary is shorter than the full episode; examples and assessments reflect the participants’ experience and views.

The main thread of the material
01

Fitness functions from genetic algorithms

Sergey Baranov joins a few minutes after the start, introduces himself briefly — he develops in Java and jokes that he can do neither mobile nor frontend — and delivers the talk he had prepared for the first stream. He met the term fitness function while writing up genetic algorithms: it measures how well a solution fits a changing context. A human eats anything and lives at very different temperatures, but if it changes too fast he does not survive; the function is the oxygen level and the temperature range in which he stays alive. An architectural fitness function is the same set of decisive parameters: speed of shipping functionality, performance, cost of the solution. The difficulty is the thresholds: when customers start leaving, how to measure security, why a hundred per cent of tests must be green when the product does not die at ninety-nine. Sergey's suggestion is to push a parameter to its limit: ten per cent degradation does not kill you, seventy does, because the system stops answering.

Nor should there be many parameters. Genetic algorithms have an endless number of them, thousands and millions, while architecture tries to keep no more than ten, because they conflict: an absolutely secure bank is one you cannot get into, an absolutely convenient one lets in anybody; a sub-second response time argues with the demand to encrypt all traffic. The first difficulty is working out which parameters matter without killing your application to find out; the second is normalising them to compare performance with security. In Sergey's own Life-like model of animal species with randomly changing parameters, one generation sometimes needed hundreds of millions of mutations to survive: five of a thousand made it, and the next thousand left completely different ones. Hence the conclusion for architecture: the number of viable designs is effectively unlimited, and synchronous or asynchronous interaction does not matter as long as the fitness function is satisfied.

02

Connascence, coupling and change locality

The authors reduce the chapter to coupling in its very first paragraph, and the conversation runs into connascence — a word none of the participants will translate into Russian. Alexander says he met it earlier in another book and decided to leave it as it is. The definition they write out: two components are bound by connascence if a change in one requires a change in the other, while coupling is any dependency that forces no change. The objection comes immediately: connascence of type is just coupling of type, and the same goes for naming and position. The term, by the participants' reckoning, was proposed in the nineties — 1993 and object-oriented design get mentioned, though nobody vouches for the precision — and it is known mostly through a site they reckon is among the first hits in the search for how connascence differs from coupling. Occam's razor is invoked too: if a simpler model explains what happens, a more complex one is not needed.

The chapter itself gets a hard time: ninety per cent of the coupling types listed at the start never appear again, and the text is assembled from the same authors' other books plus a little Evans, while conclusions about evolutionary architecture proper are almost absent. For contrast they cite Vlad Khononov's book on DDD, where every gun on the wall goes off: coupling by time, by operation, where it hurts and how to rewrite it; his book on coupling is expected this year and they plan to invite him with questions. What they do find useful is locality. Changes are split into local, non-local and architectural ones, with the note that local architectural ones exist too, and a good architecture maximises the local kind. The worst case is strong coupling spread across the whole system: you can break a component you have never heard of. A single chapter, the participants note, packs in bounded context, quantum, connascence, coupling and microservices — bold, and rather like marketing: if you did not follow it, go read the next book.

03

The quantum, the broker and the mycelium

The architectural quantum is defined as an independently deployable artefact with high functional cohesion, high static coupling and synchronous dynamic coupling; the last part, one of the hosts says, causes the most confusion wherever he has seen it discussed, including at work. The authors call the microservice the ideal quantum, and Sergey qualifies it: if delivery is not automated and the boundaries are not drawn along the domain, it is a service-based solution somebody named a microservice and now complains that it keeps falling over. The database behind a service belongs to its quantum — without it the service will not come up. The broker is where they argue: in a shared cluster with a notional two hundred topics the data of different services never meets, yet one changed setting breaks everybody. Sergey answers that blocking dependencies are what to look at: syntactic and semantic coupling through messages remains, but services do not have to change simultaneously, and the broker is precisely what breaks the blocking coupling. The kinds of isolation are listed separately — by domain, state, time, failure and space — backed by asynchrony, service discovery, circuit breakers and bulkheads.

The boundaries of a quantum still feel blurred: the authors explicitly call the operating system a separate static dependency, and it is unclear where the orchestrator cluster and virtualisation belong. Hence the digression about the mycelium in an Oregon forest which, by one participant's account, covers over eight hundred hectares, has lived almost two and a half thousand years and stays genetically one organism: in the book's terms, one quantum. The verdict: all models are wrong, but some are useful. The best quote of the chapter, they agree, compares reuse to organ transplantation rather than assembling Lego: nobody prepared the code for reuse, a service for consumer loans will not work as well for corporate ones, and the more reusable code becomes, the less usable it is. The closing argument is about data products: they can be deployed independently, yet the authors put them into the same quantum as the service and coin a cooperative quantum. One participant explains it by the single source of data: a data product is one more interface, only others integrate with you, not the reverse. At the end the hosts admit they are extracting less than usual from this book and suggest pausing these authors' titles in the club's vote.

Takeaways

What to take away

  1. 01A fitness function is set by a threshold rather than a wish: push the parameter to the value beyond which the system stops being viable, and keep no more than ten such parameters.
  2. 02Connascence describes links where changing one component forces a change in another, while coupling is any dependency; connascence is maximised inside a boundary and minimised across boundaries.
  3. 03Duplicating code between services is cheaper than creating a blocking dependency; what is dangerous is duplicated meaning, when one business transaction is smeared across two services.
  4. 04A vast layer of analysis work, as Sergey observes, goes into digging out coupling: a business process spread over a dozen systems is excavated again by every new team.

Sources