Domain-Driven Refactorings
Warning: This is unfinished work in progress. I hope it can nonetheless be of use.
“All happy families are alike; each unhappy family is unhappy in its own way.” This Anna Karenina principle applies not only to families but also to software systems. Different software systems suffer from different diseases and we need different cures for these. Many legacy systems suffer from one or more of the following diseases:
- The legacy system has become a big ball of mud because no one controlled the dependencies and now everything is connected to everything else.
- The domain knowledge is entangled into one huge domain model whose parts fit together only partially or even contradict each other.
- Business source code and technical source code are mixed, and thus the replacement of obsolete technology or an extension of the domain logic becomes a Herculean task.
- People are organized in a team structure that is unsuitable for making fast progress.
Carola Lilienthal and I have collected the treatments for these diseases and written them down in our book Domain-Driven Transformation. To perform the transformation, one needs domain-driven refactorings, which are collected here on this website. The catalog is split into four categories:
- Strategic Refactorings: Help with splitting a monolith architecture into bounded contexts.
- Tactical Refactorings that Support Strategic Refactorings: The smaller steps that the strategic refactorings are built of.
- Socio-technical Refactorings: Reorganize the teams. This is often enabled by and/or accompanying strategic refactorings.
- Tactical Refactorings that Strengthen Domain Knowledge: Change the inner implementation of a bounded context.
In the descriptions I follow the classic Fowlerian format of Introduction/Motivation/Mechanics/Example(s).
The Catalog
Strategic Refactorings |
---|
Extract Bounded Context |
Implement Bounded Context from Scratch (and Replace it in the Monolith) |
Extract Shared Kernel |
Tactical Refactorings that Support Strategic Refactorings |
---|
Extract Specialized Service |
Extract Specialized Entity |
Extract Specialized Anemic Entity |
Extract Specialized Table |
Replace Method Call with Domain Event |
Tactical Refactorings that Strengthen Domain Knowledge in the Code |
---|
Enforce Ubiquitous Language |
Replace Primitive with Value Object |
Combine Value Objects |
Heal Entity Anemia |
Remove Setter |
Replace Setter |
- Move Domain Logic from Service Down to Entity (=> Move Statements into Function, Move Statements to Caller) |
Introduce Contract |
Replace Collection of Entities with Entity in Its Own Right (TODO) (=> there is a relationship to Encapsulate Collection) |
Replace Collection of Entities with Repository (TODO) |
Split Active Record into Aggregate and Repository |
Split Repository into Interface and Implementation |
Extract Entity from Smart UI |
Extract Service from Smart UI |
Acknowledgement
I thank the participants of the open space “Domain-Driven Refactorings” at KanDDDinsky 2021 conference. As you can see on the right, many of the above described refactorings have been collected there.
In Refactoring, Martin Fowler describes many standard refactorings; Refactoring Databases complements that book on the data side. Josh Kerievsky shows in Refactoring to Patterns how to refactor to the patterns from the Gang of Four’s Design Patterns. On this page, I’m collecting refactorings that help to introduce patterns originally described in Domain-Driven Design by Eric Evans, Patterns of Enterprise Application Architecture from Fowler, and others.
Bibliography
Ambler, Scott W. and Pramod J. Sadalage. Refactoring Databases: Evolutionary Database Design. Upper Saddle River, NJ: Addison-Wesley, 2006.
Evans, Eric. Domain-Driven Design: Tackling Complexity in the Heart of Software. Boston: Addison-Wesley, 2004.
Fowler, Martin. Patterns of Enterprise Application Architecture. Boston: Addison-Wesley, 2003.
⸻. “Strangler Fig Application.” Bliki. June 29 2004. https://martinfowler.com/bliki/StranglerFigApplication.html.
⸻. Refactoring: Improving the Design of Existing Code. 2. ed. Boston: Addison-Wesley, 2019.
Gamma, Erich, Richard Helm, Ralph Johnson, and John Vlissides. Design Patterns: Elements of Reusable Object-Oriented Software. Reading, MA: Addison-Wesley, 1995.
Kerievsky, Joshua. Refactoring to Patterns. Boston: Addison-Wesley, 2005.
Lilienthal, Carola and Henning Schwentner. Domain-Driven Transformation: Modularize and Modernize Legacy Software. Boston: Addison-Wesley, 2024.
Skelton, Matthew and Manuel Pais. Team Topologies: Organizing Business and Technology Teams for Fast Flow. Portland, OR: IT Revolution, 2019.