Software becoming legacy is a common problem. Developers often do not want to work on legacy systems, as it is often complicated, uses technologies no longer in demand, and involves more maintenance tasks. Also a legacy system holds back a company as it is slower to introduce new features demanded in the marked and by the customers.
At the start of the legacy systems life, it was, of course, not legacy. It was probably built with the latest and greatest, and developers were eagerly and quickly developing the system.
Fast forward, and this system is seen as hopelessly outdated, obscure and unmaintainable. What happened? Let us look at the top 10 reasons your software became legacy.
10. Developers who Build CVs Instead of Software
The IT industry is moving quickly, and companies are demanding experience with the latest technologies. Many developers know this and include new technology in the stack to build their CV first and to help the company second.
The project leaders are often totally unaware of this. The developers can simply argue that this is what needs to be done, and the project leaders will accept it and even push for it, even though it is a detour that will delay the project and reduce the quality. Had they known the consequences, they would never accept it.
Many developers see their stay at a company or in a project as temporary. Thus, they are less concerned about the long range consequences of technology choices and more concerned about their next career move.
Counteracting this effect requires accepting that the phenomenon exists, and having leadership who enforce a clear focus on the company’s long term goals. The leadership must carefully make technology choices and stick with them. Changes in the technology choices must be carefully evaluated to be in the company’s interest first and foremost.
9. It is Fun to Learn New Things
Learning is fun, but learning in itself does not make you money and making no money is not fun. What then is better than learning at work and making money while doing it? Most developers will not shy away from learning at work. This is a problem for the business, however, since simply learning the latest things often does benefit of the company, and, as we see in many of the other reasons listed in this article, embracing the new because it is new is another reason your software becomes legacy.
Introducing new things often cause software to become legacy because the system will evolve into a patchwork of different approaches. This unnecessarily increases complexity. Also, as new things are added, the old things are considered outdated. The amount of outdated code gradually increases and the software becomes legacy.
This is a double whammy: Developers learn instead of work and produce legacy instead of stable, solid, long term software.
Software development sometimes consists of long stretches of engineering work where business processes are automated. Compared to learning and experimenting with new technology, this can often be seen as rote and boring work.
Software development is not that different from other construction work. Often, it is well known how to solve a problem, and well known tools and techniques are sufficient to solve the problem. In other words, developers need to accept the fact that sometimes software simply needs to be built, and there is little room for learning new things. The simple reason for this is that the company’s goals does not require the developers to learn new things.
Sometimes, of course, it is useful to learn new things. This should be driven by the leadership of the company making a careful decision that learning the new thing is in the company’s interest. In this case, the learning is a part of the explicit company strategy and is, of course, no longer a problem.
When introducing something new, the leadership should seriously consider refactoring the old code so that the whole codebase is up to date with the latest technology choices. If this is done, the complexity of the software is kept under control.
It might be surprising, but fashion is a big thing in IT. We are definitely not thinking about clothing, but it is analogous. Clothing people for survival is today basically a solved problem, thus clothing designers produce fashionable clothing by inventing new designs and color-combinations. Differentiation and conformity drives fashion: You don’t want to use the same clothes as your grandpa, but you do want to use the same clothes as your favorite actor, startup-guy or musician.
The same can be seen in software. Building many kinds of software is today a solved problem, so developers differentiate themselves from the uncool and conform to the cool. This creates a flux of different ways of developing software, without any actual professional reason.
7. The Fad of Today is the Bore of Tomorrow
What is new and shiny today might be old and boring tomorrow. The IT industry is famous for moving quickly. As fast as your developers learn the latest fad, they will reject it when the next big thing comes along. Some software systems are a museum of old fads come and gone. This is one of the characteristics of legacy software.
It is therefore important to recognize a fad. New technology should be carefully considered before embraced.
6. Focusing on the Benefits of the New and the Drawbacks of the Old
When new and obviously better technologies have been established, it is very easy to see the problems of old technology. It is not as easy, however, to see the problems of new technologies. Drawbacks often become apparent after years of use, and are thus not as visible for new technologies.
Thus, when comparing technologies, it is important to take all aspects of the technology into account. This might be difficult, but strong decisions regarding technologies is what protects software from becoming legacy.
5. Unnecessary Dependencies and Too Tight Couplings
Reusing software is great, and during a software’s lifetime, more and more software is reused. This creates an expanding list of dependencies that are typically pulled in with package managers such as maven or npm, or used as heavier dependencies over web services.
If the dependencies are sloppily chosen, there is an increasing risk they themselves become legacy, which in turn turns the part of your software that depend on them into legacy. If the dependencies were unnecessary, then this could have been avoided.
A related issue is tight coupling to dependencies. Tight coupling means that there is a lot of code that interact with the dependency and that the interaction is filled with details of the dependency. Such thick and tight integrations basically means that the software’s fate is bound to the dependency’s fate. This is common and sometimes unavoidable. The architect should carefully think about whether there really needs to be a tight coupling, if it really does not need to be, then avoiding creating the tight coupling could protect the software from becoming as legacy as its dependency.
4. Unnecessarily Complex Architecture
The architecture of software is its highest level structure. Decisions taken when creating the architecture has long range consequences. A typical example is programming with many programming languages. A modern web application might reasonably use two or three different programming languages, but using six or more programming languages most likely unnecessarily complicates the architecture.
If the architecture is unnecessarily complex, it will be difficult for new developers to work on the system. This causes the quality of the code to deteriorate over time.
The basic reason is that it is unnecessarily difficult to understand the system, and modifications to the code might not take into account the relevant details of the architecture.
Having an architecture which is as lean as possible will reduce the chances of this being a problem.
3. Unnecessary Parts of Programming Languages
There is a heavy focus in the developer-community on idiomatic code. Idiomatic code utilizes the distinctive properties of a certain language extensively. The reason is a belief that idiomatic code is quicker and less error prone to write.
Idiomatic code comes with some rather unknown drawbacks. The first is that code is forever bound to a particular programming language. And when this programming language goes out of fashion, the code turns into legacy. Also, less idiomatic code is easier to translate to other programming language simply because the code uses more common constructs present in all programming languages.
Another issue is complexity. Most modern programming languages are surprisingly complex. If you are not already experiencing this in your current project, then look up programming language puzzlers or quizzes online. Most of us know the gurus with 10+ years experience who know a lot of details of a programming language. Their expertise enables them to produce some of the tightest solution to some problems. When someone not as skilled encounters this code, they will have to spend a few hours Googling and discussing with colleagues before being able to understand what is going on. These costs are often ignored, but it is a part of the cost of the solution. A simpler solution might have taken a little more code and time, but it might not incur the same cost later on.
Needlessly to say, modifications to fancy code is error prone. So is creating new code that relates to the fancy solutions.
Some companies reduce the complexity of the programming language they use by introducing guidelines, static analysis and code reviews. These reduce the complexity of the programming language simply by disallowing some of the constructs in the language. Over time, however, such guidelines have a tendency to change and be violated.
2. Not Limiting Developers
A software system usually has an architecture which is carefully chosen. A new developer or a less skilled developer might not know about the architectural decisions. The developer might therefore produce code that violates the architecture, thereby actually creating a more complex architecture. This emergent architecture is implicit in the code, and therefore other developers do not know about it. This is a slippery slope towards increasing complexity.
In other words, not limiting developers usually means creeping complexity.
There are several ways to limit developers. For example, the range of possibilities for a developer should be categorized. Next, a developer should be given access to the appropriate categories. Certain categories of changes should be limited to architects. For example, the choice of introducing new programming languages.
The limitations should be enforced primarily through code reviews assisted by static analysis. This is one way to keep complexity under control.
1. Not Modularizing Software and not Limiting the Scope of the Modules
Modularizing software means splitting it up into smaller parts, each with a limited scope and size, and with clearly defined responsibilities. This has long been popular and most agree it is a good idea.
What happens over time, however, is that the modules expand into a group of monoliths. One reason is that the modules are not limited. For example, if a module is limited to only stateless functions, it is guaranteed not to expand beyond that. Another example, limiting a module to abstracting the interaction with payment systems. A realistic way to ensure this limitation is through code reviews.
The basic theme of this article is that software should have an architect and technological lead who protects the software long term. The architect should make careful and informed decisions about technological choices and how to deal with changes in them. The architect should ensure that the software is modularized, and that each module has only necessary dependencies and complexity level of both the structure and programming language. Developers working on these modules should know the scope of the modules and respect the bounds placed on them. The technological leadership can be enforce this primarily through code reviews but also static analysis.
How Progsbase can Help
Progsbase is a system for creating computational modules that will last a long time. It includes static analysis that will check for compliance with the carefully selected features that combines productivity and understandability with longevity. Progsbase also comes with a large library that is basically immune against becoming legacy.
Software becoming legacy is a considerable drawback of a company, and makes it less dynamic in the marketplace. The good news is that software can be protected against becoming legacy and that it is a matter of having the correct knowledge and tooling.
The progsbase team can also assist with legacy avoidance and refactoring to improve the protection against becoming legacy in the future.