The strategies of software development have always been and will continue to be a permanent topic of debate and contradictions, which generates at the same time an environment favorable to important ideas. Throughout the years, I have had the opportunity of dealing with different opinions and attitudes regarding this topic.
Taking into consideration both the convergent opinions as well as the divergent ones in respect to a certain vision is a fundamental condition of the evolution of software development strategies.
The architecture of a system cannot be defined independently; it depends on a given context, fact which introduces the later into equation, as an important and defining aspect in choosing the architectural pattern. The analysis of the component elements will cast more light upon choosing the architectural form of the solution we are developing.
Each of us are formed and trained following a certain path, which determines the forming of different visions on technology. The universities we graduate from, the companies we go through, the projects we work on, the individual study contribute to the formation of a package of information which makes us see things one way or another. On the other hand, the rate of technological evolution makes every one of us assimilate the novelties to a certain degree.
An important aspect, in such a dynamic environment, is constituted by the filtering of the information. The appearance of tens and hundreds of technologies on time unit requires time for assimilation, analysis criteria, labeling capacity. Most of the times, our professional formation is the result of other people's conclusions. We embrace the technological preferences of the companies we are working for, take over the know-how automatically, most of the times. All these form a system of values and knowledge which determine our work capacity. We begin to mature the moment we are able to detach ourselves from this entire system of technological processing and see things in an objective manner.
The maturing of the architectural vision is acquired along with the participation in a bigger and bigger number of projects and through the interaction with more and more diverse work teams. The variety of projects enlarges our degree of perception of the problem. Each project contributes to the formation of a new perspective or the redefining of an existing one.
Your appetite for complexity or your tendency for simplicity are traits that characterize us ever since our years in school. It is easy to notice that right from the first years in school, some students prefer complex solutions in mathematics and others are satisfied with the shortest way to the solution of the problem. These tendencies are determinant throughout one's entire life.
Complex solutions bring new arguments and open a wider area of visibility when they are well chosen. The qualities we endow a software solution with can bring direct benefits in scalability or the strength of the application. However, if the relations between the important aspects are not well defined, then complexity can be a major impediment. It's not seldom that I have encountered applications which were trying to combine the most important technologies of the day with the most recommended architectures, but in exchange they required a complex framework, with no well-defined directions, a kind of a chess without clear rules. The process of development and then that of maintenance of such an application can be extremely difficult.
Complexity can be an attribute of chaos or one of evolution. The architecture of the system has to bring clarity, flexibility and it has to endow the system with strength. The simplicity of a complex system is in the fact that a great number of pieces on the game board create a clear, intuitive view.
The software system of nowadays are subjected to different requirements than those produced 20 years ago. The Agile development environment brings extremely diverse requirements for the systems, so that the emergence of some puzzle pieces, hard to anticipate at the beginning of a project, almost becomes evidence.
The needs of the clients are in continuous growth, and therefore the software systems must anticipate and integrate some architecture with a high level of flexibility and adaptability to a complex environment. This fact brings up the need of creating some more and more complex and intelligent systems. The inversion of control has become a main requirement in the systems design, where each component should have the quality of being well defined and independent from the others. The same important role is also played by the interface oriented design. Right from the start, we may say that the applications that do not observe the new simulation standards are a trouble maker.
An important constraint is given by the deadlines for product delivery. They can put some considerable pressure on choosing the architectural elements. A complex architecture requires proportional development time. However, an architecture that is too simple can bring a wide range of problems. Thus, the tendency of sacrificing the unit testing modules is almost obvious, in most of the situations. There is a subconscious tendency to consider that the functionality of the modules is guaranteed by the mere fact that there is written code, but we should pay more attention to this aspect.
The Agile environment requires the adding of new functionalities at a very fast pace, which does not allow good planning and analysis of all the implications, as Waterfall does. Thus, the introduction of errors is almost inherent. But along with the adding of a package of features, the number of errors will be rather difficult to control and the time allotted to unanticipated events will be spent mainly on fixing the errors introduced during development.
The need for creating error free modules requires the anchoring of every feature in a system that ensures behavior integrity. An excellent design pattern which allows us to ensure a backup of this type is offered by test driven design. This design pattern ensures the creation of some state indicators of every aspect.
The testing based design (improperly called testing) imprints the solution of a somewhat different development pattern from the classical one. A mind formed on the classical programming principles omits important details in the process of design, focusing on other components. The test driven design (TDD) allows the detection of problem items right from the designing stage. Even if for many, this type of development seems atypical, it guarantees strength. Thus, the effort of integrating this design procedure leads to very good results in the following stages.
The systems whose architecture does not observe certain clear norms for component and layer networking, as well as the modules whose behavior cannot be continuously guaranteed (through checking mechanisms) constitutes an impediment often encountered. The development deadlines are not met, generally, because of these two categories of problems. These drawbacks can be easily surpassed if the architecture of the software systems is conceived and built with maturity.
The designing of the systems should have a primary place in software development; otherwise, the applications may show a high degree of fragility. The criteria for architects' formation are very complex. Even if many companies promote developers with less than 8 years of experience on such positions, I think it is a too short time for formation. The process of defining the profile of an architect lasts a longer period of time and it also involves other factors than the purely theoretical training. The interaction with a great number of projects is important in order to better understand the conclusions of important authors, as well as the arguments that they are based on. Maturity in system designing comes when a programmer has assisted to the development of a rich number of applications, in order to be able to understand the drawbacks, but also be able to define powerful systems. Only such an experience can guarantee the strength of the created systems.