In economics, there is a contradictory statement that says:
Never take sweaty costs into account
Streams are standing, according to Wikipedia ( https://en.wikipedia.org/wiki/Sunk_cost ):
In economics and business decision making, sunken costs are costs that have already been incurred and cannot be recovered.
When in-line costs are connected with political pressure or personal ego (which manager wants to be the one who admits that they made a bad decision or did not control the results properly, even if it was inevitable or could not be directly controlled?), This leads to a situation called an escalation of obligations ( https://en.wikipedia.org/wiki/Escalation_of_commitment ), which is defined as:
a model of behavior in which an individual or group, faced with the increasingly negative consequences of a decision, action and investment, will continue, and not change its course - something irrational, but in accordance with decisions and actions previously done.
How does this relate to code?
Having a fairly long career as a software developer, one common thread I found is that when faced with a complex or ugly code base (even if this is our own two years ago), our first instinct is to want to throw away the old, ugly code and rewrite it from scratch. If this is a familiar code base, then this is usually due to the fact that we are now more familiar with project traps and business requirements than we were when we started the project, so we (perhaps subconsciously) seek the possibility that to correct our past sins by erasing them with perfection. If this is an unfamiliar code base, we often tend to oversimplify the problems that original developers encounter by masking āsmall detailsā in favor of a ālarge imageā of architectural thinking and often blowing budgets and time frames because of a lack of understanding of the complex pettiness of business cases, initially intended to address.
Then there is a whole concept of technical debt, which, like financial debt, MAY and WILL accumulate to such an extent that the code base becomes technically untenable. More and more time and resources are being invested in troubleshooting, extinguishing fires, and overly complex improvements, making progress ahead costly, complex, and dangerous. Projects take longer and longer due to defects and break away from project work to eliminate production problems. After a few hours, the āincidentsā begin to become the expected operation, and not some rare outbreak. Instead of backing down and starting to do things right to increase our future productivity (and quality of life), we find ourselves in a situation where we are forced to add more and more technical debts to meet deadlines - the technical equivalent of credit card cash advances, to make minimum payment to another card.
That is all said, this does not mean that we should correspond whenever possible, and we should not avoid rewriting working code at all costs. Both extremes are potentially wasteful, and the latter, as a rule, lead to an increase in liabilities (because at all costs means complete neglect of costs, even if these costs are completely ahead of the benefits). What is about to happen is an objective assessment of the costs and benefits of rewriting code compared to incremental improvements. The challenge is to find someone with experience and objectivity to make this decision correctly. For us developers, we tend to rewrite, because it tends to be much more interesting and more interesting than working with some crappy outdated code base. Business managers tend to be biased towards another direction, because rewriting imposes some unknowns with a slight tangible immediate benefit. The result, as a rule, is the lack of a real solution, which then by default continues to reset the clock into the existing code until some circumstance requires a directed shift (or the developer secretly rewrites the code and usually gets a flogging for it).
I worked on code bases that were somewhat salvaged, albeit ugly. They did not adhere to established practices or standards, did not use templates, were ugly, but they performed their intended functions well enough and were flexible enough to be modified to meet expected future needs for the expected duration of the application, although this is not glamorous, it was it is perfectly acceptable to keep this code alive, making additional improvements when the opportunity arises. Fulfilling otherwise would bring little benefit than it would look beautiful. I would say that most of the code I should rewrite this about? the question arises under this category, and I find myself explaining to the junior developers on the team that although it would be great to rewrite YetAnotherLineOfBusinessApp into {insert the whizzbang structure here}, this is not necessary or desirable, and here are some ways we can improve it ...
I also worked on codebases that were hopeless. These were applications that barely started in the first place, as a rule, lag behind the schedule and the state with reduced functionality. They were written so that no one but the original developer can understand what the code ultimately does. I call it read-only code. After it is written, any attempt at a change potentially leads to a system illegible error of unknown origin, which leads to a panic in wholesale censuses of massive monolithic code constructions that have no purpose, except to teach the current developer what is really happening with a variable artfully named obj_85 at runtime reaches a line of 1,209 nested 7 levels deep if... else... , switch and foreach... with instructions somewhere in the DoEverythingAndMakeCoffee(...) method. Attempts to reorganize this code fail. Each path you walked leads to a different problem, as well as to other paths, and then to the paths of this branch, and then turns back to the previous path, and after two weeks of reviewing one class, you understand differently that, although it may be better encapsulated, the new code is almost as drunk and confusing as the old code, it probably contains even more errors, because the original intention of what you reorganized was completely unclear, and not knowing exactly which business cases led to the initial disaster, first of all You can be sure that you are fully reproduced functionality. Progress almost does not exist, because translating the code base is almost impossible, and something so innocent renames the variable or uses the correct type, gives an exponential number of unforeseen side effects.
Trying to improve codebases like the ones above is a futile exercise. Refactoring usually results in 80% rewriting anyway, and the end result is almost never improved by 80%. As a result, you have something very inconsistent, and the new code has a lot of trade-offs that should have been implemented in the interests of interacting with outdated code (half of which is not needed, because the legacy code that the new code needs to interact with later gets refactoring anyway). There are only two ways that can be followed ... continue to gain technical debt by cracking āfixesā and modifications, hoping the application is outdated (or you switch to another project) before it crashes under its own weight, or someone makes a business decision and risks making full correspondence. I hate both of these options, because usually it means that until something critical works or the project keeps up with the schedule, and then you spend the next three months of nights and weekends trying to get something breathable which probably should never have been alive in the first place.
So how do you decide?
- How well does existing code work? Is it reliable and relatively free from defects?
- Can people on my team understand what this code does with a reasonable degree of effort? If I bring an experienced developer, can he / she have enough knowledge of this to be productive in a reasonable amount of time?
- To do what should be simple defects, to carry out geological measurements of time in order to correct it; so much so that we cannot make real improvements or fulfill the project deadlines?
- Is such a codebase so fragile and life expectancy that the applicationās ability to adapt to future expected business needs is doubtful?
- Does the existing code meet the original functional requirements?
- Is your organization even susceptible to investing in an application, or will someone (especially someone at a higher level in the org diagram) be referred to solve the problem?
- Can you provide a financial or risk justification supported by hard facts to make a business example for rewriting?
- If, after taking full account of the time and costs of rewriting (including the development of appropriate specifications, quality testing, stabilization after preparation and training, does it make sense to start rewriting the code (we, the developers, tend only to think in terms of coding time)?
- Do you have a choice? Is it possible that the existing code meets the requirements (because if not, rewriting huge rows will be part of the project and is considered an āimprovementā instead of rewriting)?