Software design is the process of organizing sections of code through its functions, objects, methods and data structures, the general architecture of the system and the interaction between its components.
The choices you make about the software architecture affect the efficiency with which you can meet customer demands for the introduction and modification of features.
Making the right choices at the beginning of a project but, above all, maintaining a good architecture over time means paying attention to the software not having unnecessary or duplicate components and remains intelligible to the developer community.
It is clear that today, with the use of iterative and incremental development methodologies provided by Extreme Programming¹ (XP) with Test-Driven Development² (TDD) cycles, we tend not to design an entire system from the green field. Rather, in accordance with the Agile³ methods, customer requests are sorted by value by developing the most important elements first and, only later, the least important ones.
It is clear that this mode can involve rewriting software components, this is inherent in the Agile approach, but one should never lose sight of the principle that the level of revisiting and the complexity of the design must remain adequate to the problem to be solved. Otherwise I could see rapid drifts in terms of project time and budget.
Several authors, from Kent Beck⁴ to Martin Fowler⁵ to Robert Martin⁶ to Corey Haines, have been involved in simplicity in application design, but the rules are essentially four. It is clear that in reality not all of them are applicable for each context, but also a subset of them is a contribution to the cause of Extreme Programming!
The first rule is, at all times, to satisfy the code tests before each refactoring. If the code fails the tests, it will also be difficult to spot any bugs. Whatever stage the code is, it has to work. This rule aims to ensure the production of the necessary value to the customer.
A snippet of code should immediately say what it does and should leave no room for surprises. The names of variables, methods, classes, packages, services, functions, configuration, test system, and in general all software components should describe what they do through a nomenclature that is understandable at the time of their writing and in the future.
We must produce source code today always considering the possibility of intervening later, even after several years, when the historical memory in the company may no longer be there. The code has to speak for itself.
The third rule has to do with removing part duplication. Multiple software components that do the same thing have an unjustified ordinary and evolutionary maintenance cost. The phenomenon often occurs in the presence of very large projects involving a multitude of development professionals. It is then refactoring the moment when, with the help of testing, overlapping components of the code are assimilated.
In general, in software development, we refer to the principle known as DRY⁷ (Don’t Repeat Yourself) to indicate the reduction of duplication in a broad sense, that is, also related to the architecture of the entire solution.
The fourth and final rule is a mere optimization. The application, applying the YAGNI⁸ (You Aren’t Gonna Need It) principle, should not include code of which there is no cogent need. The rule is to remove any unnecessary code by resisting the impulse to design components for any future needs that you are not sure about.
Ex post, if the application contains parts that at the time of realization seemed like a good idea, but that were never realized, it must be slimmed down.
Sometimes it is difficult to minimize correctly when you are focused on the details, for this reason it is good to take a step back occasionally and evaluate the result.