Why Domain Modeling?

One barrier to considering rich domain model architectures is a misconception about the value or purpose of a domain model. To some, creating a domain model seems a throwback to earlier days where design and modeling were perceived to be discrete, lengthy, and mostly unproductive activities.

When object technology was young, several notable authors made a strong distinction between object-oriented analysis and object-oriented design and programming. Ostensibly, during object-oriented analysis you analyzed a task that you wanted to automate and developed an underlying conceptual (object) model of that domain. You produced a set of task descriptions and a model of objects that included representations of domain concepts and showed how these objects interacted to accomplish some work. But you couldn’t directly implement these objects. During object-oriented design you refined this analysis model to consider implementation and technology constraints. Only then, after finishing design, would you write your program. The implication was that any model you produced during analysis or design needed extensive manipulation and refinement before you could write your program.

But even in those early days, many of us blurred the lines between object-oriented analysis, design and programming. In practice, how we worked was often quite different than suggested by the popular literature of the time. We might analyze the problem, quickly sketch out some design ideas and then implement then. We might use CRC cards to model our objects (which we would then discard). There weren’t distinct gaps between analyzing the problem and designing and implementing a solution. Sometimes different people did analysis while others did design and programming; but many times a developer would do all these activities. Sometimes, we created permanent representations of some models (in addition to our code). It depended on the situation and the need.

These days, I rarely see anyone produce detailed object analysis or design models. In fact, design and modeling have gotten somewhat of a bad wrap. Good object design is deemed too difficult for “average” programmers, and there isn’t time apart from coding to think about the domain and come up with any models.

The most common object models I see are created for one of two purposes: small conceptual models constructed to gain an understanding of significant new functionality; or informal design sketches intended to provide a quick overview to newcomers or non-code reading folks who need to “know more” about the software. A lack of modeling (unless you consider code or tests to be models—I don’t) is prevalent whether or not the team is following agile practices. The most common models I do see are very detailed E-R models that are more implementation specifications than models. They don’t leave out any details making it hard find the important bits.

Understanding and describing a domain and creating any model of it in any form takes a back seat to most development activities.

But if your software is complex, rapidly changing, and strategic and you aren’t doing any domain modeling, you may be missing out on something really important. If your software is complex enough, you can greatly benefit from domain modeling and thoughtfully doing some Domain-Driven Design activities.

For example, Domain Driven Design’s strategic design is a conscientious effort to create common understanding between business visionaries, domain experts and developers. Initial high-level domain discussions lead to understanding what is central to the problem (the core domain) and the relationships between all the important parts (sub-domains) that it interacts with. Gaining such consensus helps you focus your best design efforts and structure (or restructure) your software to enable it to sustainably grow and evolve.

But it doesn’t stop there. If you buy into domain modeling, you also commit to developing a deep shared understanding of the problem domain along with your code. Your mission isn’t to just deliver working functionality, but to embed domain knowledge in your working solution. Your code will have objects that represent domain concepts. You’ll be picky about how you name classes and methods so they accurately reflect the language of the domain. You will have ongoing discussions with domain experts and jointly discuss and refine your understanding of the domain. Along the way you may sketch and revise domain models. You’ll strive to identify, preserve, strengthen and make explicit the connections between the business problem and your code. When you refactor your design as you gain deeper understanding, you won’t forget to reflect the domain in your code. Your domain model lives and evolves along with the code.

As a consequence, there isn’t that big disconnect between what you code and what the business talks about. And that can be a powerful force for even closer collaborations between developers and domain experts.

Good enough domain models

Eric Evans talked about Domain-Driven Design at our Portland SPIN meeting Wednesday. Eric’s thesis is that unless you capture the “ubiquitous language” that people use to talk about the functions of the business and create a domain model representing object concepts, you are developing software at wrong level of detail. Instead of talking about Shipping Routes, Legs, and Itinerary, you’ll be talking about “creating rows in the stop table” for each port along a shipping route. Why create Itinerary and Leg objects when you can get by stuffing a database table with “stop” records? Because it makes other parts of the system easier to program. Re-routing cargo gets easier if you can remove all Legs after a particular destination and splice one Itinerary onto another one. Lack of a domain model can severely limit the effectiveness of software (and make it hard to maintain systems and add new functionality).

Creating a domain model is more complicated than just capturing the language people use to talk about system functionality and creating software objects with appropriate names. In complex software, development teams often work on different sub-problems. Each subsystem may need its own model. Meanwhile, subsystems and teams still need to define appropriate ways to communicate with each other. In addition to ubiquitous languages, you need to define the appropriate common languages for inter-system/inter-team communication. Nothing is ever easy!

Eric’s masterful talk motivated me to ponder about why developers often end up with muddy models instead of ones that more clearly incorporate domain concepts. Eric says that domain modeling isn’t looking for a perfect model, only ones that are “good enough” to support the hardest problem well. Why don’t more development teams end up with “good enough” models? I suspect there are many reasons. What constitutes “good enough” can be so subjective that people don’t want to get bogged down. They give up and take the easiest paths, not the simplest ones. For lack of a good object to relational mapping tool, some developers may compromise on database tables being ‘good enough’ approximations to classes. And their models get compromised. There are many reasons why software falls short of capturing “ubiquitous language” in a domain model. I suspect that a big reason is that it isn’t always obvious that a model is needed. If your code shuffles data back and forth from the UI to a database with few edits, why create a model? Only when there is significant behavior and computation, does a model pay off. Now if we all could agree on what “significant” means. If you have ideas about what constitutes significant enough behavior to warrant a model, I’d like to hear your thoughts.