While studying logic at University, I picked up a concept that changed my thoughts about software development. I don’t know how it translates to English, but something like: there is a difference between being sound and complete.
Take an example; you start asking questions to a sound person. If the person answers, then the answer is correct. However, the person will not always answer.
Continuing with the example, if the person is complete, there will always be an answer. However, you do not necessarily know whether the answer is true. A good example is kids. They will never say they do not know anything; they give it a go. The kids are, of course, not sound.
Sound & Complete
The first realization is that a paradigm/concept/technique/programming language in the domain of software development is sound and complete in a much smaller scope than sound.
When thinking about something being sound, I realized that that is only the case in a subdomain, such as DDD, in the example above. There is no technique, programming language, or methodology that is sound in the entire domain of software development. At least, I cannot think of anything. This is probably another way of saying there is no silver bullet.
There is also the case that something may be sound in one subdomain and utterly false in another. Let us take the example of the Object-Oriented Programming (OOP) subdomain in software development. Here there is an emphasis that objects should keep their state. The way to handle complexity is to limit the number of states the overall system can have by clearly defining operations on objects to alter their internal state. The enemy in good OOP is an anemic model where you use objects without defining the state changes as operations on them and instead have a large and ever-increasing number of services changing state all over the place. However, in the Functional Programming subdomain, an anemic domain model is the way to go. Instead, you use the type system to limit the number of allowed changes and keep the complexity at bay.
How do you respond to someone saying that an anemic model is horrible and not the “best practice”? It can go for a hefty debate where everyone can fight to “win the argument,” or we can discover a new subdomain and insight into the ever-so-complex domain of software development. In this subdomain, your axioms suddenly are false.
Complete? – Example from Domain-Driven Design
Continuing with an example from Domain Driven Design. Once you read the book, you learn a lot, and I am absolutely a fan. However, the principles are by no means complete in the domain of software development, and neither does it try to be. The book beautifully states that the ideas and techniques are for software subdomains that have:
- Large domain complexity
- AND everchanging rules
Instead of seeing the subdomain, no pun intended, where the statements in DDD hold, people read it as there are statements that are true AND complete for all software development. There are many scenarios where DDD is a horrible idea: POC, a startup that needs to hack together something that gives them a couple of more months to survive, or a subdomain where the complexity does not change. Let’s say you are creating a system for periodic systems. Does that change? Do we need to model everything using DDD, aggregate roots, and whatnot? Of course not.
Listening to great minds in software development, I have noticed that they often spend a significant amount of time specifying the context of their ideas – in essence, they are defining their subdomain in which what they are about to say is complete and thus sound.
The ultimate challenge is to find out which subdomain in software development will solve the problem best and to clearly define that subdomain whenever discussing or onboarding new team members.
Creating a complex software system requires multiple different skill sets from multiple subdomains. Instead of trying to try to merge all of them into a domain and finding one technique that is complete, an impossible endeavor, we need to navigate between many subdomains and choose just the correct amount from each.
Creating good software systems is an incredibly difficult task. Realizing that the best solution encompasses many different subdomains(UX, programming, design, etc) and that something may be true in one subdomain and false in another will create better teams where each member learns more. No subdomain is sound and complete for the entire domain of software development, aka, there is no silver bullet. And maybe that is the most fun and rewarding about working in software development.