I’m a pretty old guy so I decided to write book reviews. The goals of this exercise are:
- write something in my blog and mimic some sort of activity here
- write book essentials on granite WordPress platform. I can always open these notes and refresh memory when mental debility finally reaches me. The only problem is not to forget website address.
I would recommend this book to everyone. Junior developer won’t get it at all. He probably would find it boring. The senior developer would remove it from reading queue in 10 minutes. Senior developer with good self-analysis would regret he didn’t read the book 10 years ago. I would force students to read this book from the first page till the last page if I were the Computer Science professor at Stanford.
You should know software design patterns and be familiar with their real-world applications. Your Computer Science professor should explain many software architecture design problems otherwise.
What this book is about
Book tells about Domain Driven Development (DDD)software engineering methodology application. The book describes how DDD ideas are applicable in the real world.
All people involved in a project should use the same terminology. Let’s say we working on ETL processes. ETL (extract-transform-load) helps business to gather data from various sources into one place. Wallmart can extract-transform-load transactions from regional stores into central storage every night. BART can extract-transform-load busses GPS-tracks into analytics system.
There is typical confusion in terms: pipeline or workflow, action or stage, job or stage or action. The confusion starts to leak into documentation, code, UI labels and we have one entity with many names at the end. What to do? Write out terms and definitions.
- We have an action.
- Action describes job configuration.
- A job is some configurable program.
- A Sequence of actions is workflow.
Now we have set of core entities of a domain.
We tend to build generic software systems with unlimited expansion capacity in any business direction. It never works, specialized systems always win. Human is much smarter than a shark and it can do much more than a shark. Shark was swimming and hunting last 420 mln years, human will never swim and hunt better than a shark.
What to do?
- Don’t try to build generic system, you will fail.
- Listen to business guys and extract contexts.
- Apply bounds to contexts.
- Define the ubiquitous language for the context.
ETL problem could have several contexts:
- Jobs running and doing some data changes.
- Actions that declare configuration for jobs.
- Workflows that connects actions
Model Driven Design
Never ever try to skew your domain with software language or software framework. Your domain has the highest priority, it must always affect software choice.
What do do? Business people can read the code, most likely code smells if the business can’t read it.
- Try to catch a guy and show him the code. See if he can decrypt your ideas from the prototype.
- Change software tool or business guy and iterate one more time.
Yeah, I know, it won’t work with non-motivated business, but it’s the communication problem. Solve communication problem first then do try to apply DDD practices. No matter how good your software is if was disconnected from domain experts during the development process. The business team must invest the almost equal amount of time.
Layered architecture, Services, Modules, Repositories, Factories, Intention-Revealing Interfaces, Side-Effect-Free Functions, Assertions, Standalone Classes, Closure of Operations, Declarative Design
I would say it’s a side note of the book. Architecture design covered much better in other books. I suppose the author has the assumption that you know how to solve software architecture problems.
Closure of Operations
Special node about “Closure of Operations”. it means that Calculator.add(a:Int, b:Int) should return Int or Long, not String. It’s the math term, addition is closed under Integers. Any addition of two integers returns integer. Return type or value shodn’t be surprise to API user.
What do to?
Do not try to hack problem and put some data validation feature into client UI module. Most likely data validation should happen on the server side. Change scope, simplify functionality but never try to consciously increase technical debt since debt grows each day without your conscious contribution.
Entities and value objects
Entities have properties and these properties change from time to time.
Yeah, it’s an art of listening and composing. Let’s say we model Public transport system. The bus driver should be expressed as the entity, the bus should be the entity too. Current bus location (latitude, longitude) gathered by GPS tracking system is a value object. Location is written once and immutable. It refers to a single bus. A bus driver can quit, turn sick. A bus could be broken, transferred to a different line or removed from the bus depot.
Most likely business wants to track events and it should be reflected in model somehow. Driver illness could be expressed as single value object with start and end illness dates. Driver entity could be associated with the history of his illness records or vacation requests.
You will define many entities and value objects during domain area exploration. Don’t hesitate to hide many of them away from the end user. The idea is to hide nonrelevant details and relations. Bus Depot, Bus Driver, Bus could be aggregates, top-level entities. Bus driver sickness history, vacation history are details of Bus Driver. We can guess that they are less important, the end user doesn’t need direct access to them. The other important recommendation is to avoid bi-directional relation where possible. It’s much harder to implement and support them even in relational representation. A bi-directional many-to-many relation could be extremely complex to implement and maintain.
Obvious relations between entities, obvious system behavior, well-shaped context bounds will help you to keep the supple design. It’s consequence, not cause.
I would say it’s a bit sophist’s term. These contours are about API boundaries. Imagine calculator REST API implementation. There are several ways to do it:
- Register A value and get A id.
- Register B value and get B id.
- Call “add’ method and pass A id and B id to id and get C id
- Call “getValue” method and C id to it. Get value of “add” operation.
Looks like the masterpiece of software overengineering, correct? Why not just pass A value and B value to “add” method? Conceptual contours are about API granularity. Does end user needs to register “add” operands one by one, does he really need these tiny details?
Define your model as the standalone module with almost zero dependencies and share it between teams. Share and reuse your ubiquitous language.
Do not implement tight integration with an upstream software product. Create an isolating layer between upstream API and your service. This extra layer will help you to keep bounds of contexts. You would need to translate upstream model to your domain in the most cases. Anticorruption layer aim is to translate “remote” language into your domain specific language.
Big Ball of Mud
The term describes a legacy system with spaghetti inside and without any kind of strategy. Setup fence around it and don’t allow mud to flood into other systems. Basically, that’s all you can do.
You must know software design patterns before reading the book. You must talk to business people and involve them in the design phase.