Domain-Driven Refactorings

Warning: This is unfinished work in progress. I hope it can nonetheless be of use.

Cover of the book *Domain-Driven Transformation*

“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
Socio-Technical Refactorings
Form Cross-Functional Team out of Layer-Team Members
TODO: Form Enabling Team out of Layer-Team Members
Form Second Team out of Partly Layer-Team and First-Team Members
Form Second Team out of Only Layer-Team Members
Move Operations Team Member to DevOps Team
Assign Bounded Context to Existing (Cross-Functional) Team
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 (=> there is a relationship to Encapsulate Collection)
Replace Collection of Entities with Repository
Split Active Record into Aggregate and Repository
Split Repository into Interface and Implementation
Extract Entity from Smart UI (TODO) (=> there is a relationship to Separate Domain from Presentation)
Extract Service from Smart UI (TODO)

Acknowledgement

Flip chart of refactorings gathered at KanDDDinsky 2021

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.