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.

Domain-Driven Design Applied

Vaughn Vernon’s new book, Implementing Domain-Driven Design, is full of advice for those who want to apply design principles and patterns to implementing rich domain model applications.

Check out my interview with Vaughn for InformIT. We discuss why he wrote this book and some important new Domain-Driven Design patterns and their architectural impact.

There is much to learn about good design of complex software from this book. In future blog posts I plan to unpack some of the meatier domain-driven design concepts and reflect on how best to apply them to designing enterprise applications.

Why Objects?

As I’ve been working on a position statement for an OOPSLA panel reflecting on the roots of modern software development practices while looking to the future, I’ve been thinking hard about why I got hooked on object technology. Compared with structured programming and design, objects seemed significantly better at handling complexity. Object programming languages were an earth shattering improvement over the procedural and assembly languages I used when I first encountered structured design techniques. Instead of simply following conventions, object programming language constructs forced me to bundle together meaningful operation and data. Object-oriented methodologies generally incorporate the principles of structured design but OOD seems much more than an incremental improvement over SD. Instead of focusing on a thread of control and managing its complexity via procedural decomposition and structured control constructs, object design enables me to break a composition into thousands of semi-autonomous entities with structured roles and responsibilities. Objects offer me a completely different way to think about computation. This way of thinking empowers me to deal with a level complexity that I could never have dealt with only using structured design techniques. Object technology encourages me to form abstractions—objects—and to design how small neighborhoods of them interact.

Responsibility-driven design offers thinking tools that enable developers to conceive of an implementation in terms of interacting roles and their responsibilities. It provides a vocabulary for describing designs that helps developers communicate complex ideas and make tradeoffs more effectively. Agile practices, by emphasizing working code that satisfies customers, seek to reduce accidental complexity by admonishing you to design simply and grow complexity only when needed. Eric Evans, in Doman-Driven Design: Tackling Complexity in the Heart of Software, offers tactics for identifying, preserving, and sharing a common domain model. Refactoring tools have taken tediousness out of making changes and modern application development environments have made it possible for development teams to “hum” by testing and building incrementally. These all represent progress.

But at the end of the day, they cannot reduce the complexity inherent using diverse tools, platforms, and technologies that make up a typical sprawling IT system. While OOD/OOP did give us an order of magnitude improvement over previous techniques and tools, we still don’t have the order-of-magnitude better approach we need to sort today’s complex environments and minimize the gaps and seams that are inherent when diverse technology comes together in a complex system. In the meantime, thank goodness for the framework builders who give us various ways of linking objects with relational databases and for little languages and tools that take the tedium out of repetitive (error prone) tasks of gluing things together. We live in a complex world where objects will continue to make a lasting, significant contribution. What will be the next breakthrough in software development that will subsume the principles of OOD (and transitively SD) and provide the next order of magnitude improvement? I’m not sure. While I don’t think there are any silver bullets out there, I look forward to discovering and encountering even more effective practices, technologies, and techniques that allow us to address inherent complexity head on.