In former posts I have written about the importance of adaptability and maintainability. In this post I’d like to focus on the engineering aspects. I mean to say, how these issues could be addressed from a software engineering point of view.
First and foremost, I like to think on software as a set of interrelated systems and components, each one could be actually implemented as a function or an object, to name but a few. In fact, these implementations details are not so important, the critical point of view is that all of them should behave as a unit of functionality. Both the concept of unit of functionality and systems are thoroughly discussed in software engineering literature. But I like to highlight this approach, instead of using concepts as API or service, because, on the one hand, it allows me to reflect on how each single software component should behave and, on the other hand, the idea of a system, its dependencies, its ability to be simulated is pretty aligned with my education in another engineering field.
Be that as it may, this concept or unit is utterly important. Let’s imagine a complex machine comprised of several components or even systems. For the sake of example, we could talk about several gear systems, an engine or even the individual gears. Obviously, not only should the full system work smoothly but also each individual component. Furthermore, the gears could be used in another complex machine. So then, they should work properly and according to certain specifications. Hence, when we talk about software we are talking about similar concepts and ideas, following system design principles and proper system or component reusability.
Further to this, problems arrive when we try to explain how software systems should be built, how components should be isolated or how can reusability could be achieved. It is, indeed, not an easy task since acquiring a proper comprehension requires that the teacher has the knowledge and the learner is actually ready to apprehend it.
Certainly, we have developed patterns, SOLID principles, and tools like TDD, but I wonder if an unmature developer is able to understand how these tools could allow him to develop a proper engineered system or component. From my point of view it is hard without a proper mentorship and teaching-by-example.
In order to clarify my point of view, I would like to showcase an actual example of a subsystem we are currently working on, a whatsapp/telegram bot application, a directed question based one. As a matter of fact, this is not a complex application. Its difficulty comes from system’s decomposition and proper testing of each component. Let’s try to make the exercise that you are junior developers and you have to build this solution, what could be your approach? If your team leader is kind enough, he could suggest you to start developing the Telegram Bot and when it works properly, to build the Whatsapp one. Unfortunately, this is a recipe for disaster from the point of view of system design. If you wonder why, take into account that I stated that you were junior so, probably, you would build your bot following an approach similar to the following one:
If you are senior enough you will have certainly expressed your discomfort at the idea of such a piece of shit, since, among other problems, that strategy drives to implement Whatsapp Bot from scratch. Actually, the problem is not only placed on the junior side, but also on how the senior, the team leader or the project manager has given instructions or has followed project development. A better instruction set, from the point-of-view of system’s architecture should have included the following blocks:
It could be considered that a software system written this way is complex. Well, in fact, it is. Even more, if we take into account that each individual software component should be written taking into account similar ideas such as isolation or behavioral design. Advantages are subtle, but important:
On the other hand, any system has a certain degree of complexity. Recovering the analogy of the gear system, knowing what a gear does not mean that you know how to create an automatic watch. Ignoring the complexity of this kind of work, the actual engineering behind it, only drives to unmaintainable products and more costs than the initially expected.