I'm a big proponent of constant, ruthless refactoring. However, I've only recently realized that I've completely overlooked a type of refactoring that's crucial to delivering a well-designed, customer-centric application. Until now I've been focusing on refactoring that mostly improves the technical quality of the code - the type of stuff largely captured in Martin Fowler's catalog of refactorings: renaming methods and classes to better reveal intent, removing duplication, extracting behavior so that classes and methods have a single reason to change, etc. However, reading Eric Evans's book Domain-Driven Design: Tackling Complexity in the Heart of Software has opened my eyes to another type of refactoring that's probably even more important: changing the code so that it reveals a richer, more insightful domain model that is closely aligned with the problem domain itself. This type of refactoring is known as refactoring toward deeper insight.
Refactoring toward deeper insight is not a substitute for technical refactoring, as both are absolutely needed. In his book Evans states that refactoring toward deeper insight:
"superimposes another level [of refactoring]: refactoring to a deeper model. Executing a refactoring based on domain insight often involves a series of micro-refactorings, but the motivation is not just the state of the code. Rather, the micro-refactorings provide convenient units of change towards a more insightful model. The goal is that not only can a developer understand what the code does; he or she can also understand why it does what it does and can relate that to the ongoing communication with the domain experts."
So refactoring toward deeper insight produces a powerful domain model whose benefits are obvious and immediately useful. That's why it's essential that this type of refactoring not be ignored. However, it requires a rigorous process Evans calls "knowledge crunching" - sorting through a bunch of information surrounding the problem domain to abstract out a set of concepts that best represent the most relevant aspects of the domain. This is more difficult to do than pure technical refactoring, thus Evans suggests three things to focus on when attempting refactoring toward deeper insight:
1. Live in the domain.
2. Keep looking at things a different way.
3. Maintain an unbroken dialog with domain experts.
Despite its additional effort and unfamiliarity to me, I fully intend to try more refactoring toward deeper insight. And of course, I'd love to hear others' experiences with this kind of refactoring and any suggestions they have.