Apples and Oranges
How often do we hear statements like how immature software engineering is compared to other engineering disciplines? Of course, construction building is a very old craft where engineers could collect huge amounts of knowledge, methods, and experiences over thousands of years.
On the other hand, there is a huge gap between traditional engineering disciplines and software engineering:
- While other engineering disciplines are focused on specific domains, software engineering is supposed to support countless problem domains.
This is why we came up with technologies that are more general in terms of problem domains such as:
- Architecture Definition and Specification Languages
- Generic Design Patterns (GoF)
- Components and Services
However, there is a huge trap using such approaches. Due to their general and generic nature, they are far away from the realities of the problem domain. Thus, communication between software engineers and non IT-knowledgeable stakeholders does suffer.
It is interesting how many experts still emphasize those general-purpose tools and technologies. So to speak, they are addicted to the One-Size-Fits-All drug.
For instance, look at architecture description languages that introduce general components and connections. The problem is that for a concrete problem domain, such generality simply does not work. It is a difference, whether you are dealing with a medical imaging modality or a VoIP platform. Yes, we can … call all building blocks of such systems components or subsystems. And, yes we can … call all interaction paths connections. But, here we are unifying different concepts under one common umbrella.
What software people often forget is that there are two universes:
- the Solution Domain with all its supporting tools and technologies. In this domain, general-purpose approaches as the aforementioned make sense,
- AND the Problem Domain.
In the Problem Domain we can not naively leverage concepts like UML, Components or General Design Patterns. Instead, we need to follow a Problem Domain First Approach. Thus, it is necessary to start with concepts of the problem domain. What does that mean in practice?
- Introduce DSLs and Domain-Driven-Design to cover the problem domain instead of relying on UML. As a matter of fact we can use the underlying meta-model of UML as a base. It is possible to evolve such a language in an iterative approach.
- Think about the basic building blocks not as components and subsystems, but use the terminology of the problem domain. You can define your own problem-specific components, subsystems, or services for this purpose. This is exactly what we did for a very large Enterprise Communications System.
- Consider the availability of Analysis Patterns for your problem domain and subdomains. Use them if available.
Building the Software Architecture then consists of mapping the problem domain to the solution domain. How could we do that? I mentioned the Onion Model several times. So steps could be:
- Understand the problem domain and build a model of it jointly with domain experts
- Leverage use cases to understand what the system under development is supposed to deliver from a black-box view.
- Use the problem domain model to map the use cases to the problem domain artifacts introducing further functional aspects.
- Stepwise extend the architecture by using strategic quality-attribute scenarios with descending priorities.
- Prepare the architecture for tactical requirements by using the tactical quality attribute scenarios with descending priorities.
- Do all this just considering three abstraction levels to limit complexity.
- Apply architecture patterns to structure the overall system.
Mind the Change! Unlike in many other disciplines, software is considered so soft that it should even support strategic late changes. This is like switching your project goal from creating a coffee machine to creating a power plant. Unfortunately, customers are rarely aware of this problem because they are being constantly told by sales and marketing that changes are no problem. Thus, make customers and maybe even more sales and marketing aware of this fact. And use an agile approach to embrace change. But also have courage to deny changes. This is another reason why the Problem-Domain-First approach is so important. How else could you know what changes or extensions are typical for a problem domain? Think of the tax legislation in your country. It is not helpful to only think of interception and extension hooks or Strategy pattern instantiations in this context.
All general approaches for software engineering have their value and can be used as the underpinnings of your systems. But they should not be used for covering the whole software development from problem domain to solution domain. This is also what we can substantially learn from other engineering disciplines.
Thus, don’t mix apples and oranges. Otherwise, the result may disappoint you.