As I'm thinking more about architecture lately, I decided to skim this book. The text struck me as frequently fluffy, vague, and verbose, with writing that couldn't get to the point quickly and clearly. There's also a bias towards internal company projects, not B2C nor B2B software. And generally, object-oriented thinking with all its incidental complexity is over-represented in this book, though they do give good history as to why in Ch.8.
- Content: B, reasonable heuristics, and some interesting/broad surveys of software history.
- Presentation: C, too verbose.
I've paraphrased and extracted what I consider useful signal from noise, in point-form below. The summary is simple: separate data from functions. That goal is not quite natural for object-oriented code and requires the conscious and repeated effort the book describes. But data|functions is the heart-and-soul of functional programming, so pick your paradigm accordingly!
- System architecture should reflect end-users' mental model of their
world; that model has two parts, form and function:
- form, what the system is; reflects the stable structures of
business/domain over time.
- Architecture is: more about form than structure; more about compression than abstraction; and less about solving user problems.
- First design step, partitioning - techniques include:
- Partitioning and/or classification: focus on what the system is apart from what it does.
- Separate the components of your architecture according to their different rates of change.
- Partition s.t. each part can be managed as autonomously as
possible, esp. considering who will work on what part.
- They even advocate letting "human considerations drive the partitioning, w/ software engineering concerns secondary."
- Avoid partitioning domains
- Table 5-1 is interesting: three kinds of "primary
- Modules organized by business domain
- Then be sure to staff each location around a business domain.
- Modules organized around markets
- Then be sure to staff each location around some market.
- Modules organized by solution domain - disfavored
- Modules organized by business domain
- Second design step, select a style
- Partition by domain knowledge.
- When you don't have domain knowledge, partition by end-user's mental model and their notions.
- Think and capture architecture in the most compressed expressions possible that still covers the scope of your business/domain.
- Consider commonality and variation in your domain, and how to express that in your language.
- Provide an API (for the rest of your architecture) to DSL-generated code.
- Use standards, adapters to integrate 3rd party software.
- Documentation: Have a domain dictionary.
- Third design step: rough framing of code
- Go from careful/thorough analysis → APIs
- Keep domain classes (types, I'd say for FP) spare and "dumb"; properties should be more stable than functions/methods.
- Use assertions and contracts for safety, and to express interfaces between modules, and generally to capture/assert (domain) knowledge.
- Use both static and dynamic checks.
- function, what the system does; or end-user experience and
- User stories useful here.
- Distinguish User Profiles/Roles/Actors
- Know why someone would want to use your software; consolidate accordingly.
- Tie user intention to system responsibilities.
- MVC vs. DCI (Data, Context, Interaction)
- MVC, lumps system-is and system-does together, but often
those change at different rates and involve different people.
- Updates its data at the request of commands from the Controller
- Notifies appropriate views when its state changes
- Can be asked to register/de-register Views
- Presents a particular representation of the data to the user
- Can ask Model for the current value of data it presents to users
- Can handle its own input
- Together with the Controller, handles selection
- Creates and manages Views
- Handles selection across Views
- Passes commands to the Model
- Handles commands that apply to the entire window
- DCI, separate code representing system state from code
representing system behavior, i.e. architecture separate into
data/domain/what-is vs interaction/feature/what-does
- Not FP; rather, it's about "injecting collections of methods into a class."
- Looks like a lot of incidental complexity when done via OO languages. Even the Python example looks full of incidental complexity.
- MVC, lumps system-is and system-does together, but often those change at different rates and involve different people.
- form, what the system is; reflects the stable structures of business/domain over time.
- All stakeholders should be involved early on to explore
- Five major stakeholders: end-users; the business; customers; domain experts; developers
- Programming languages should enable expression forms in code; initially while we're still exploring, we avoid details of structure.
- Express complex system functionality in use cases, capture and iterate models of interaction between end-user and system.
- Use roles (i.e. traits) as a formalism expressing essential behavior of the system (like how classes capture domain structure).