Architecture & practice·topic 1 of 10
Design, structure and tradeoffs
The words for why one arrangement of the same code is better than another. Almost every design review disagreement is one of these ideas being felt by one person and named by nobody, which is why the argument goes in circles until someone says the word.
Read in order · tick what you already know
- 01
you changed one module and three tests in a directory you had never opened went red.
Coupling
- 02
the code for one job is spread over four files, and each of those files also does three unrelated jobs.
Cohesion
- 03
the call only works if you remember to call the other method first, and nothing tells you that.
Temporal coupling
- 04
you wanted to change the retry policy and had to read a HTML template to find where it was set.
Separation of concerns
- 05
two teams keep editing the same class for two entirely unrelated reasons and keep colliding.
Single responsibility
- 06
another team reached into the field directly, and now you cannot rename it without breaking them.
Encapsulation
- 07
you wrote order.getCustomer().getAddress().getPostcode() and a change three objects away broke your line.
Law of Demeter
- 08
you called something that looked like a getter and it wrote a row to the database.
Command-query separation
- 09
the method called save() also sent an email, and somebody found that out in production.
Principle of least astonishment
- 10
nobody used the option because nothing about the API suggested it was there.
Affordance
- 11
the ORM hid the SQL right up until you had to read the query plan to fix a timeout.
Leaky abstraction
- 12
the function reads like a sentence for three lines and then drops into byte offsets.
Level of abstraction
- 13
you followed the call through four interfaces to find the one line that actually does the work.
Indirection
- 14
the controller called the database directly and three people commented on the pull request.
Layered architecture
- 15
the business rules import the Postgres driver, so testing a discount calculation needs a database.
Dependency inversion
- 16
you needed to test the payment path and there was nowhere to slip a fake in without editing the code you were testing.
Seam
- 17
you swapped the storage backend and did not have to open a single pricing rule.
Orthogonality
- 18
the new feature was two things you already had, wired together, and nothing new was written.
Composability
- 19
the subclass needed one method overridden and inherited four others it never wanted and cannot remove.
Composition over inheritance
- 20
'customer' means one thing to billing and something else to support, and the shared table forces one of them to be wrong.
Bounded context
- 21
the code says Account, the spec says Subscription, and in standup everyone says plan.
Ubiquitous language
- 22
everything ships together, so one bad line in someone else's feature blocks your release.
Monolith
- 23
you kept the single deployable and made a module boundary something the build fails on when crossed.
Modular monolith
- 24
the service you own deploys on its own schedule and you have never waited for another team's release.
Microservice
- 25
you split it into six services and still have to deploy all six together, in the right order.
Distributed monolith