Software Engineering as Systemic Anatomy & Pathology
Treat a running system as an organism rather than a diagram and a different set of questions becomes natural. Diagrams show structure; organisms have to stay alive โ they regulate themselves, they have organs with distinct jobs, and when something goes wrong in one part the symptom often shows up somewhere else entirely. This lecture maps software architecture onto anatomy deliberately, not decoratively: each anatomical layer corresponds to a real, separately-reasoned-about concern in system design, and the mapping earns its keep when it changes how you diagnose a failure.
Anatomical Mapping
business logic, decisions"] Skeleton["๐ฆด Skeleton
interfaces, ADTs, boundaries"] Autonomic["โ๏ธ Autonomic system
GC, thread pools, circuit breakers, logging"] Limbs["๐ฆพ Limbs & actuators
I/O, DB writes, network calls"] Immune["๐ก๏ธ Immune system
validation, types, assertions"] Brain --> Limbs Brain -.regulated by.- Autonomic Skeleton --- Brain Skeleton --- Limbs Immune -.guards.- Limbs Immune -.guards.- Brain
| Anatomical layer | Software equivalent | Governing idea |
|---|---|---|
| Skeleton | Interfaces, abstract data types, module boundaries | Parnas's information-hiding criterion: modules should be decomposed around the decisions likely to change, not around the flowchart [1] |
| Autonomic regulation | Garbage collection, thread pools, circuit breakers, logging | Runs continuously and silently; failure here doesn't crash the "mind", it degrades everything gradually โ the software equivalent of losing temperature regulation |
| Brain (cortex) | High-level business logic and decision-making | Where domain rules live; the layer everyone means when they say "the logic" |
| Limbs & actuators | Side effects โ database writes, network calls, I/O | Where the system touches the world, and therefore where the world's failure modes (timeouts, partial writes) leak back in |
| Immune system | Input validation, type systems, assertion boundaries | Meyer's Design by Contract: precisely-stated preconditions and postconditions as the antibodies that reject malformed input before it reaches the cortex [2] |
Systemic Pathology
The reason the anatomical framing earns its keep is that it predicts where symptoms appear relative to their causes, and in living systems as in software those are often far apart. Charles Perrow's study of high-risk technologies coined "normal accidents" for exactly this shape of failure: in tightly-coupled, complex systems, small, individually-survivable faults interact through pathways nobody designed for, producing failures that are not attributable to any single broken component [3]. A thread pool quietly exhausting itself (an autonomic problem) does not announce itself as a resource error โ it shows up as the cortex appearing to "hang", or as actuators timing out downstream, because the layer that failed is not the layer where the pain is felt.
Nancy Leveson's systems-safety work generalises the same point into a design method: in a sufficiently complex system, treating an accident as a chain of component failures misses the accidents that arise purely from unsafe interactions between components that were each, individually, working exactly as specified [4]. This is precisely why "which component is broken?" is often the wrong first question for a systemic failure โ the better first question is which two correctly-functioning components are now interacting in a way nobody designed for.
Meinhard Lehman's laws of software evolution add a slower-moving version of the same pathology: a system that is used continues to be changed, or it becomes progressively less satisfactory (Lehman's first law); and unless deliberately maintained against it, a system's structure will drift toward greater disorder over successive releases (Lehman's second law, on "declining quality") [5]. Architectural decay is not a discrete event โ it is closer to the organism ageing, and it is detectable long before it is symptomatic if anyone is measuring coupling and complexity trends rather than only counting open bugs.
Surgical Refactoring
If the system is alive, changing its internals without killing it requires something closer to surgery than demolition: maintain the patient's vital functions (backward compatibility, uptime) throughout the procedure, change one structure at a time, and verify function is intact before closing up. Martin Fowler's definition of refactoring makes this explicit as a discipline, not just good taste: a refactoring is a behaviour-preserving transformation, verified by tests, applied in small enough steps that the system is never observably broken between steps [6]. The strangler-fig pattern โ routing an increasing fraction of traffic to a new implementation while the old one keeps serving the rest โ is the direct engineering analogue of a staged surgical replacement rather than a transplant done in one irreversible cut.
The anatomical framing also explains why some "obviously good" refactors are dangerous: replacing an autonomic component (say, swapping a circuit breaker implementation) looks lower-risk than touching the cortex, because it isn't business logic โ but autonomic failures are exactly the ones that present as vague, distributed symptoms elsewhere in the organism, which makes them the hardest to link back to the change that caused them. Nygard's operational patterns for production systems treat circuit breakers, bulkheads and timeouts as safety-critical infrastructure precisely because of this โ they fail quietly, at a distance, from wherever they were touched [7].
References
- Parnas, D. L. (1972). On the criteria to be used in decomposing systems into modules. Communications of the ACM, 15(12), 1053โ1058. https://doi.org/10.1145/361598.361623
- Meyer, B. (1988). Object-Oriented Software Construction. Prentice Hall.
- Perrow, C. (1984). Normal Accidents: Living with High-Risk Technologies. Basic Books.
- Leveson, N. (2011). Engineering a Safer World: Systems Thinking Applied to Safety. MIT Press.
- Lehman, M. M. (1980). Programs, life cycles, and laws of software evolution. Proceedings of the IEEE, 68(9), 1060โ1076. https://doi.org/10.1109/PROC.1980.11805
- Fowler, M. (1999). Refactoring: Improving the Design of Existing Code. Addison-Wesley.
- Nygard, M. T. (2007). Release It!: Design and Deploy Production-Ready Software. Pragmatic Bookshelf.