Tudor Girba, Kursleiter für agile Software Architektur, erläutert, wieso die Architektur einer Software ebenso relevant ist wie deren Funktionalität.
I often encounter teams that work on systems that have great current value but that are expensive to evolve. In other words, the future value of the system is highly influenced by its structure. Indeed, when I talk with technical people, they broadly agree with the idea that architecture is as important as functionality, at least in the long run.
If we truly believe this, we should act accordingly. If two things are equally important, we should treat them with the same way. Given that functionality of a system is considered a business asset, it follows that the architecture is a business asset as well. That means that we should stop perceiving the effort around architecture as a cost, and start seeing it as an investment.
Testing is like an insurance
Functionality receives significant investments in testing. Developers produce automated tests that complement the production code, while dedicated testers might take care of strategic and exploratory testing. In a way, testing is like an insurance, but unlike other insurances, this one is essentially guaranteed to pay off later on. Automatic testing pays off not because people are careless, but because the system entails way more details than can fit in someone’s brain.
Not everything is done automatically though. There is room for manual work, too. For example, exploratory testing. We want to explore ways to break the system, and that require creativity. But, once we know how to break the system we want to delegate the regression testing to the machine. That’s because humans are notoriously ill equipped for handling regression testing.
Architecture can be tested as well
Do you check the architecture with the same rigor? Do you have automatic architectural checks that prevent you from deploying when they fail? Not doing so means that half of the business assets remain uninsured. Half.
How can you test architecture automatically? You need to first see the code as data. The same applies for configurations, logs and everything else around a software system. It’s all data, and data is best dealt with through tools.
Let’s consider an example. Let’s say you work on splitting a monolithic application and in this process you notice that component A relies directly on the implementation of component B, instead of only its interface. This is not a visible problem when both components reside in the same deployment, but it is an impediment for deploying them as separate services. Let’s devise a test to expose the problem.
componentA := model allNamespaces named: ‘com.example.a'.
componentBImplementation := model allNamespaces named: ‘com.example.b.implementation'.
classesInAThatRelyOnBImplementation := componentA allClasses select: [ :each |
each queryAllOutgoingAssociations atNamespaceScope includes: componentB].
If the result of this query is not empty we have wrong dependencies. Furthermore, the concrete list gives us the places that we should work through.
This is a test. Only it is not a functional test. It is a structural one. If the architecture of the system is as important as functionality we should be in position to test it just like we can test functionality. As such, it can also be made part of the continuous integration process and can guard against regressions.
Static checks are not new, and often projects actually rely on this kind of analyses. However, the way the analysis was used in our example is less often encountered in practice.
Where our example is different is that it is not a standard check that we downloaded from the web. Even if our example is not too complicated, it still relies on details that only make sense for the system at hand in the same way as a unit test only makes sense for the system at hand. This indeed implies a cost, because someone from the team has to create it, but that is exactly where the value lies because architecture is not standard. Architecture is contextual, and as a consequence, ensuring it requires contextual checks.
Testing the architecture requires investment
To make this practical, we need the costs of creating the tests to be low. Our particular example might look like a pseudocode, but it actually is an executable piece of code in the Moose analysis platform (http://moosetechnology.org). This is a platform that focuses on enabling engineers to create custom analyses and shows how the cost can indeed be inexpensive in practice.
New tools enable new kinds of practices and require new skills. Specifically, such tools allow us to affect significantly the way we approach technical decision making in software in software development, and they also allow us to make technical problem tangible to non-technical people. This is important if we want to make architecture be recognized as a business asset. And, this is the underlying idea behind the humane assessment method (http://humane-assessment.com).