2025 Public Training Schedule
January 14 – 17, 2025 – Agile Analysis and Design Patterns – Half-Day Sessions
(c) 2024 To Be Agile
Our job as developers is less about being clever or finding efficient algorithms and more about simply perceiving the problem and representing it as accurately as possible. This is an exciting shift in software development because it means our goal is really about understanding. Once we understand a problem everything else can fall into place easily. This is why I put so much value in problem-solving techniques for software developers because I know it’s the key characteristic that great developers possess.
One of the most valuable lessons we’ve learned from the object-oriented software development movement is the notion of perspectives.
There are many kinds of perspectives that we can adopt in software: caller-callee, client-server, and many others. We can even have layers of perspectives that deal with a problem at different levels of abstraction. This makes software much easier to read and understand, and because we already have the right abstractions in place, it makes it easier for software to be extended.
There are two perspectives that are critically important when building software and the interface between them often determines the quality of the system being built. I call these two perspectives domain and services.
The domain perspective has nothing to do with software. It is a representation of the domain, of the way subject matter experts think about their domain, and therefore is often rich with metaphors and a unique vocabulary. Understanding the domain and being consistent with it has a huge impact on how elegant a solution we can come up with.
Designing a system around domain entities is often the best choice for creating software that addresses the customer’s needs now and in the future. Divergence from domain metaphors can lead to overly complex software that’s difficult to stitch together.
The services perspective is a way of grouping the capabilities of the computer system in such a way that we can support the domain model. Rather than having the domain layer make calls to system APIs, we prefer to package the services on the system into entities that can be directly consumed by the domain model. These two layers of abstraction can solve some fundamental problems we encounter in building and testing code.
The point at which these two perspectives interface with each other can be the ideal place for automated tests. Testing the services layer allows us to test implementation without being implementation-dependent. It can give us a “seam” that allows us to add tests without the need to mock out a lot of dependencies. Domain tests can act as integration tests, weaving together different services.
Building systems in this way can lead us to think about problems the way subject matter experts do, and this gives us a system that’s more flexible to the needs of the particular domain.
Previous Post: « Avoiding Integration Hell
Next Post: Finding the Right Metaphors »