A son asked his father (a programmer) why the sun rises in the east, and sets in the west. His response? It works, don’t touch!Fisrt rule of programming
How often you see software systems where adding new, relatively simple features takes ages, where it is hard to find the core logic or in which part of the system to apply changes? Does reading the code gives you a headache? Does any changes you need to introduce in that software makes you sick and you want to escape from that sinking ship? Well, unfortunately, you became a victim of a software rot.
Ivar Jacobson describes a software entropy as follows:
In our daily work we too busy with adding new features as fast as possible and closing our tickets. Everyone is happy: the business sells features to customers, and we got paid, and if lucky, we even get some bonuses for that incredible performance. With time, however, software gets more complicated. You’re going to find out that adding more features takes longer and produces more bugs. This tends to grow very quickly and ends in a system which extremely hard and expensive to maintain.
Perhaps you heard of a term Technical Debt? It describes collective debt you owe to your software by doing some shortcuts when implementing some feature because you didn’t have time to do it properly. It could be on any level from overall software design to the low-level implementation. But it is a very optimistic term – it assumes that this debt will be paid off which we all know almost never happen. I prefer to think about it as a Software Rot actually and the whole practice which leads to that as a Shortcut-Driven-Development.
I think many companies just don’t realize what are the costs of maintenance of a poorly built software. But hey, wouldn’t it be nice if we can show and prove this mathematically? So that you will have strong arguments in your discussions with product owners and managers regarding the need of refactoring. Once upon a time, while I was reading Code Simplicity: The Fundamentals of Software , I reached chapter which describes the equitation of software design and it has brilliant math representation of that equation:
D = (Pv * Vi) / (Ei + Em)
Or in English:
The Desirability of Implementation is directly proportional to the Probability of Value and the Potential Value of Implementation, and inversely proportional to the total effort, consisting of the Effort of Implementation plus the Effort of Maintenance.
However, there is a critical factor missing from the simple form of this equation: time. What we actually want to know is the limit of this equation as time approaches infinity, and that gives us the true Desirability of Implementation. So let’s look at this from a logical standpoint:
The Effort of Implementation is a one-time cost, and never changes, so is mostly unaffected by time.
The Value of Implementation may increase or decrease over time, depending on the feature. It’s not predictable, and so we can assume for the sake of this equation that it is a static value that does not change with time (though if that’s not the case in your situation, keep this factor in mind as well). One could even consider that the Effort of Maintenance is actually “the effort required to maintain this exact level of Value,” so that the Value would indeed remain totally fixed over time.
The Probability of Value, being a probability, approaches 1 (100%) as time goes to infinity.
The Effort of Maintenance, being based on time, approaches infinity as time goes to infinity. What this equation actually tells us is that the most important factors to balance, in terms of time, are probability of value vs. effort of maintenance. If the probability of value is high and the effort of maintenance is low, the desirability is then dependent only upon the Potential Value of Implementation vs. the Effort of Implementation–a decision that a product manager can easily make. If the probability of value is low and the effort of maintenance is high, the only justification for implementation would be a near-infinite Potential Value of Implementation.
Let’s take a look at definition of refactoring given by Martin Fowler:
Refactoring is a disciplined technique for restructuring an existing body of code, altering its internal structure without changing its external behavior.
Its heart is a series of small behavior preserving transformations. Each transformation (called a “refactoring”) does little, but a sequence of these transformations can produce a significant restructuring. Since each refactoring is small, it’s less likely to go wrong. The system is kept fully working after each refactoring, reducing the chances that a system can get seriously broken during the restructuring.
Keeping software systems in good order requires developer teams to follow strong practices. But first of all it is your personal responsibility and should be in your culture. Continuous Refactoring is a key factor in that sense. You should refactor and improve your code on a day-to-day basis. Plan this work if you need to, explain the importance of it to the managers and product owners. You should become refactoring machines. This is not only tremendously reduce the denominator part of equation (Em), but also will force you to protect your code from breaking by implementing all kind of testing , one of which is regression testing. Each bit of refactoring will make your code better and easier to extend with new functionality. Gradually, you can switch from Shortcut-Driven-Development to Software Engineering and enjoy from what you are doing and helping business to survive in the long run.