That great book written by D. Esposito & A. Saltarello collects recipes for making solutions for enterprise applications. Though it is not a usual cookbook but guiding principals for making a ‘dish’. It is based on author’s experience and common practices from other books. Second edition published in Jan 2015 seems to be a good summation of best practices with a brief history of them for that time in .NET world.
Authors begins by giving answers to such questions as what is architecture of applications? who are software architects? how modern apps developing differs from past? We can divide the book into two parts (though authors divide it into 4 parts). In the first one there are answers to these questions: what is needed for success work? what’s required from a team? what is code quality and how to achieve it? and other. In the second one, practical recommendations for developers: what types of architecture they see? what are parts of those? main advantages and disadvantages.
To my mind to understand the book a practical experience in software developing is required, it is not for beginners.
Below are notes and mind maps of the book.
- Acknowledge requirements. See the standard: ISO/IEC 9126 (newer one is ISO/IEC 25010), it defines a general set of quality characteristics required in software products. Divide them into:
- Functional. Given-When-Then.
- Do agile (not upfront = waterfall)
- Break down the system
- Identify and evaluate technologies
- Formulate specifications
- Avoid BBM (Big Ball of Mud) (cause of failures)
- Avoid technical debt (TDBT)
- Capture all the client asked for (Ubiquitous Language — UL). Adapt quickly.
- Don’t stick to RAD when the system grows.
- Define unclear places
- Test early
- Don’t do if owner unknown
- Report in case of crisis (problem) = be open & transparent
- Monitor BBM. Symptoms: rigid; not reusable; hard to fix; other.
- Use metrics.
- Use static code analysis. R#, CodeRush, etc.
- (In team) Avoid knowledge/information silo (bottleneck)
- … (see advice for team) …
- Use tools to assist coding
- (In team) Tell coder — “bad code”, not “bad coder”
- (In team) Inspect before check-in
- (In team) (Make adequate deadlines) Don’t push people to heroes
- (In team) Encourage practice
- Reconsider architecture when requirements change (avoide BBM): continuous change
- (In mess) Get out of it first: 1) stop; 2) isolate; 3) iteratively refactor.
- (In mess) How with legacy code (code w/o tests) ?
- (In team) (On when to add a manpower)
- Do structured design
- High cohesion (about number of responsibilities), low coupling
- Do Separation of Concerns
- Do Isolate parts (hide infomation)
- Object-Oriented Design (specially for Domain Model)
- Do pertinent classes
- Program to interface
- Composition is better than inheritance
- (consider functional programming: OOD can be hard)
- OOD: aim to SOLID
- Patterns for dependency resolution: Service Locator, Dependency Injection
- (while coding) aim to Keep It Simple, Stupid (KISS)
- (while coding) aim to You Ain’t Gonna Need It (YAGNI)
- (while coding) aim to Don’t Repeat Yourself (DRY)
- (while coding) Tell don’t ask
- Don’t use patterns blindly (know them: what it is? how to? value?)
- Do Defensive programming (If-Then-Throw, Code Contracts)
- Write testable, extensible and readable code (this raises effectiveness of refactoring, which is required for maintainable code, which is always)
- Write testable code:
- write automated tests;
- Design for Testability (DFT) (technique);
- Unit tests: Arrange-Act-Assert;
- Integration tests: Big Bang (all components at once);
- Acceptance tests: on deployed solution;
- Consider TDD;
- Do high code coverage (tests) on important scenarios (critical parts: domain mostly);
- Consider Microsoft Pex (autogenerates code tests);
- Write extensible code;
- avoid over-engineering (easily extensible);
- consider interface based;
- consider plugin architecture;
- consider state machine;
- Write readable code (important: saves money and other):
- write it readable always (tests also);
- CCC: comments, consistency, clarity;
- write comments to clear up goals of code; for public things; for decisions;
- consistency: apply guidelines; do clean code;
- clarity: group code, nest code (formatting),
- make it short: aim to <30 lines per method, narrow;
- Understand domain, its segments (bounded contexts), define supporting architecture for each (see DDD)
- Crunch knowledge and implement faithfully it (it is easy to do it wrong though). DDD.
- Consider using DDD but make sure you understand it.
- Strongly consider using analytical part of DDD: defining bounded contexts and relations between them. And consider using strategic part of DDD (supporting architecture) for a bounded context.
- (UL) Define from everyday communication. (It overlaps development and domain)
- (UL) Define glossary (in plain text or in UML)
- Keep UL and model in sync
- Monitor if subdomain appear: two meaning of one term and other. And extract BC — splitting (not partitioning!)
- Consider variants of context mapping (shared kernel and other). See relations between BCs.
- Give each BC its architecture (see list of common architectures)
- Layered architecture… (description as a whole and for each layer, history)
- Consider UI/UX before domain or persistence
- Focus on interactions
- Make view model for screens
- (See advice about technologies: Asp.net mvc, Web Forms,
- (See advice on responsive design)
- (See advice on Single-Page applications)
- Consider these main patterns: TS, DM, ADM (Now obsolete: Active Record, Table Module)
- Focus on tasks (AL to orchestrate; in BL — Services)
- In TS: script per action
- In DM. When complexity… (see map)
- In ADM. For not complex only. It is more about TS. More AntiPattern
- Use DTO to cross boundaries (input/view models, across tiers)
Though this book has some introduction to DM it is better to address Eric Evan’s famous book.
(Still more chapters to outline. Please see book.)
Bounded context - BC
Ubiquitous language - UL
Context mapping — diagram of BC
Upstream and downstream contexts — upstream forces downstream to change
TS — Transact Script
DM — Domain Model
ADM — Anemic Domain Model
- Domain-Driven Design by Eric Evans
- Enterprise Applications by Fowler and others
- Patterns of OOP by GoF
- (About cohesion/coupling first) Structured Design: Fundamentals of a Discipline of Computer Program and Systems Design (Yourdon Press, 1976) / Larry Constantine and Edward Yourdon
- “Extreme Programming Explained” by Beck, 1999
- WarExtreme Programming
- Robert Martin on SOLID
- Pragmatic Programmer by Andy Hunt, Dave Thomas
- Their source code at http://naa4e.codeplex.com/