Evans talks about a “Deep Model” when he discusses refactoring, and states:

A deep model provides a lucid expression of the primary concerns of the domain experts and their most relevant knowledge while it sloughs off the superficial aspects of the domain.

Most modeling at least starts out as a “find the nouns and verbs” game, but the key is that it shouldn’t stop there. I think this overlooked key is the primary reason why refactoring to a deep model is difficult. A developer has to be listening very carefully to domain experts in order to identify some of the subtle behaviors that may be taken for granted by the expert. Most applications are not physical simulation of their constituent nouns, so it makes perfect sense that the best model will not simply be concrete nouns and verbs, but representations of underlying relationships and behaviors.

Particularly with OO programming, many developers have a habit of viewing physical objects as model objects, overlooking the possibilities of behavioral objects. Evans includes Constraints, Processes, and Specifications (predicates) as good examples of explicit behavior. Essentially, abstracting procedural code into behavioral models does two things:

  1. It provides flexibility in replacing and augmenting behaviors, which will in turn provide flexibility for domain growth.
  2. It raises the importance of the behavior by naming it and giving it a place in architectural documentation or diagrams, where previously it would only be a few sentences describing an otherwise-anonymous process nested within API documentation.

So why does this make refactoring hard? Because it’s design. Most refactoring discussions are exclusively code-level (and machine-assistable, implied by Danny Dig and other refactoring researchers). The level of refactoring that Evans focuses on is not code “cleanliness” or any sort of mathematical graph-partitioning problem.  It is the expressiveness of the model itself, and the process of converting a Nouns-n-Verbs Model into a Deep Model.

Software developers are rarely domain experts, so the biggest barrier is knowledge sharing and communication. Without domain experts pointing out the weakness, awkardness, or inflexibility of a design, software developers are left to figure it out themselves, more by chance (lucky modelling guess) or coincidence (mechanical refactoring clarifies the model as a side-effect) than by actual knowledge (domain research).