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.

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.