When is it good (if ever) to abandon production code and start over?

I was asked to review the code and report on the possibility of adding a new function to one of our new products, which I personally have not worked so far. I know that it’s easy to fake someone’s code, but I would say that it is in poor condition (trying to be as objective as possible). Some points from my code review:

  • QueueUserWorkItem abuse: QueueUserWorkItem and threads are generally used a lot, and thread pool delegates have uninformative names like PoolStart and PoolStart2 . There is also a lack of proper synchronization between threads, in particular access to user interface objects for threads other than a user interface thread.

  • Magic numbers and magic strings . Some Const and Enum defined in the code, but most of the code uses literal values.

  • Global variables . Many variables are declared global and can be initialized or cannot be initialized depending on which code paths follow and what sort of things happen. This is very confusing when the code is also skipping between threads.

  • Compiler warnings . The main solution file contains more than 500 warnings, and the total number is unknown to me. I received a warning from Visual Studio that it cannot display more warnings.

  • Semi-finished products : the code was processed and added there and there, and I think that this led to people forgetting what they did before, so there are a few seemingly semi-finished products and empty stubs.

  • Not Invented Here . The product duplicates the functionality that already exists in the shared libraries used by other products, for example, data access assistants, error logging assistants, and user interface assistants.

  • Separation of problems . I think that someone was holding the book upside down when they read about the typical three-tier architecture of the user interface access level - business level → data access level. In this code base, the user interface directly accesses the database because the business layer is partially implemented, but is mostly ignored due to the fact that it is not close enough, and the data access level controls the user interface level. Most low-level databases and network methods work with a global reference to the main form and directly show, hide and modify the form. Where a fairly thin business layer is actually used, it also tends to directly control the interface. Most of this lower-level code also uses MessageBox.Show to display error messages when an exception occurs, and most swallow the original exception. It is, of course, a little harder to start writing unit tests to test the functionality of a program before trying to reorganize it.

I'm just scratching the surface here, but my question is quite simple: would it be wiser to spend time reorganizing the existing code base, focusing on one problem at a time, or would you think about rewriting the whole thing from scratch?

EDIT . To clarify a bit, we have the original requirements for the project, so the launch may be an option. Another way to talk about my question is: can the code ever reach a point where the cost of maintaining it will become more than the cost of resetting it and starting it?

+52
refactoring
Sep 27 '08 at 23:29
source share
29 answers

Without any wrongdoing, the decision to rewrite the codebase from scratch is a common and serious mistake of managing novice software developers.

There are many shortcomings to be wary of.

  • Modes stop the emergence of new functions from the cold for months / years. Few if any companies can afford to stand for long.
  • Most development schedules are hard to fake. This rewriting will not be an exception. Simplify the previous point, now, a delay in development.
  • Errors that have been fixed in the existing code base through painful experience will be reintroduced. Joel Spolsky has more examples in this article .
  • The danger of falling victim The effect of the second system is in a nutshell: "People who developed something only once before trying to do everything that they" didn't do the last time ", loading the project with all the things that they put off when creating the version one , even if most of them should be delayed in version 2. "
  • Once this expensive, burdensome rewrite is complete, the very next command that inherits the new code base is likely to use the same excuses to rewrite. Programmers hate learning other code. No one writes perfect code because perfection is so subjective. Find me a real-world application, and I can give you an indictment and justification in order to make correspondence from scratch.

If you ultimately rewrite from scratch or not, the beginning of the refactoring phase is now a good way to both work hard and to understand the problem, so rewriting will be smoother if it’s really necessary, and also provide the existing code base an honest look, to really see if you need to rewrite.

+34
Sep 28 '08 at 3:14
source share

Really need to break and start?

If the current code does not do what you would like to do, and will cost you a lot to change.

I’m sure that someone will now link Joel’s article on how Netscape throws its code and how awful and huge a mistake it is. I don’t want to talk about this in detail, but if you linked this article before you do it, think about it: the IE engine, the engine that allows MS to quickly release IE 4, 5, 5.5 and 6 continuity, the IE engine that completely wiped Netscape ... he was new. Trident was the new engine after they dropped the IE 3 engine because it did not provide a suitable basis for their future developments. MS did what Joel says you should never do this, and because MS did, they had a browser that allowed them to completely outshine Netscape. So please ... just ponder this thought before tying Joel up and saying, "Oh, you should never do that, it's a terrible idea."

+31
Sep 27 '08 at 23:39
source share

If reading and understanding the code requires more time (if possible) than it would require to rewrite the entire application, I will say this and start.

Be very careful with this:

  • You are sure that do not just be lazy and do not bother to read the code.
  • You are arrogant about the big code you write, compared to the garbage that anyone else has generated.
  • Remember that proven working code costs much more than imaginary but not written code.

According to our esteemed host and master, Joel are things you should never do ,
It’s not always wrong to give up working code, but you must be sure of the reason.

+13
Sep 28 '08 at 0:29
source share

The rule of thumb that I found useful is that if you give a code base, if I need to rewrite more than 25% of the code to make it work or modify it based on new requirements, you can also rewrite it from scratch.

The idea that so far you can only correct code code; at some point it will slip away.

There is a fundamental assumption that you have a mechanism (for example, a thorough check of units and / or system tests) that will indicate whether your rewritten version is functionally equivalent (where it should be) as the original.

+12
Sep 27 '08 at 23:43
source share

I saw how the application was re-archived for 2 years from the moment it was put into production, while the others were rewritten in different technologies (one was C ++ - now Java). In my opinion, both efforts were successful.

I prefer a more evolutionary approach to poor software. If you can “build” your old application so that you can present your new requirements and the interface with the old code, you can make yourself easier in the new environment without “selling” the zero cost (from a business point of view) of the rewrite investment.

The proposed approach is to write unit tests for the functionalities you want to interact with: 1) make sure the code behaves as you expect, and 2) provide a security grid for any refactoring that you might want to do on the old base .

Bad code is the norm. I think that IT gets a bad rap from the business because it prefers to rewrite / rebuild / etc. They pay money and “trust” us (as an industry) to deliver reliable, extensible code. Unfortunately, business pressure often leads to shortcuts that make code unreachable. Sometimes these are bad programmers ... sometimes bad situations.

To answer your paraphrased question ... can code maintenance costs exceed rewriting costs ... the answer is clearly yes. However, I do not see anything in your examples that make me believe that this is your business. I think that these problems can be solved with the help of tests and refactoring.

+9
Sep 28 '08 at 1:50
source share

In terms of business value, I would find it extremely rare that a real case can be made for rewriting due to only the internal state of the code. If the product is addressed to the client and currently lives and brings money (i.e. is not a canned or unreleased product), then consider that:

  • You already have clients using it. They are familiar with it and can create some of their own assets around themselves. (Other systems that interact with him, products based on him, processes that they would have to change, employees that they might need to retrain). All this costs customers money.
  • Recording can cost less in the long run than making difficult changes and corrections. But you cannot quantify this until your application is more complex than Hello World. And rewriting means retesting and redeployment and probably the upgrade path for your customers.
  • Who says rewriting will be better? Can you honestly say that your company has written bright code now? Have methods that changed the source code for spaghetti been fixed? (Even if the main culprit was the only developer, where were his peers and leadership, providing quality through reviews, testing, etc.?)

For technical reasons, I would suggest that it is time for a serious re-recording if the original has some technical dependencies that have become problematic. for example, a third-party dependency that is no longer supported, etc.

In general, I think that the most reasonable step is to refactor in parts (very small pieces, if this is really so bad), and improve the internal architecture gradually, and not in one big drop.

+8
Oct 13 '08 at 21:44
source share

Two streams of thought on this: do you have original requirements? Do you have confidence that the initial requirements are accurate? What about test plans or unit tests? If you have such things, it might be easier.

Putting on a customer hat, is the system working or is it unstable? If you have something erratic, you have an argument for change; otherwise you are best refactored in parts.

+7
Sep 27 '08 at 23:37
source share

I think the line in the sand is when the basic maintenance takes 25-50% longer than necessary. There comes a time when storing obsolete code becomes too expensive. The final decision includes a number of factors. Time and cost are the most important factors that I think.

+7
Sep 27 '08 at 23:40
source share

If there are clean interfaces, and you can clearly outline the boundaries of the modules, then you may need to refactor the module through the module or layer by layer, so that you can move existing clients forward to cleaner, more stable code bases and eventually, after you have edited each module, you rewrote everything.

But, based on codereview, it doesn’t sound as if there were any clean boundaries.

+6
Sep 28 '08 at 0:29
source share

I wonder when the people who vote for breaking down and starting work have ever successfully reorganized a large project, or at least seen a large project in poor condition, which they think can use refactoring?

If anything, I am mistaken on the opposite side: I saw 4 large projects that were a mess that I advocated for refactoring, not rewriting. Only one line of source code remained on the pair, and the main interfaces changed significantly, but this process never included the entire project, which did not function as well as it did for the past week. (And the top of the trunk was never broken).

Perhaps there is a project that is so badly broken that the refactoring attempt will be doomed to failure, or perhaps one of the previous projects that I reorganized would better serve a “clean rewrite”, I don’t know how to find out.

+5
Sep 30 '08 at 22:09
source share

I agree with Martin. You really need to weigh the efforts that will be involved in writing the application from scratch, against the current state of the application and how many people use it, they like it, etc. Often we can start completely from scratch, but the cost far outweighs the benefits. I come across bits of ugly looking code all the time, but I will soon realize that some of these ugly areas really fix errors and make the program work.

+4
Sep 27 '08 at 23:42
source share

I would try to look at the architecture of the system and see if it is possible to rewrite and rewrite certain clearly defined components without starting everything from scratch.

What usually happens is that you can do it (and then sell it to the client / management), or that you will find that the code is such a terrible and confusing mess that you are even more convinced that you need to rewrite and have more compelling arguments in favor of this (including: “if we correct it correctly, we will not need to disassemble all this and make a third correspondence).

Slow maintenance will ultimately lead to architectural drift, which will make rewriting more expensive later.

+4
Sep 28 '08 at 0:25
source share

You can only give a definite yes for rewriting, if you fully know how your application works (and I fully mean it, and not just a general idea of ​​how it should work), and you know more or less exactly how to make it better. Any other cases, and this is a shot in the dark, it depends on too much. Perhaps gradual refactoring will be safer if possible.

+3
Sep 27 '08 at 23:44
source share

Copy the old code earlier and often. When in doubt, throw it away. The hard part is convincing non-technical people that maintenance costs.

As long as the value obtained is greater than the costs of operation and maintenance, there is still a positive value arising from the software. A question related to the rewriting of this question is: "Will we get even more value from rewriting?" Or, alternatively, "How much more will we get from the rewriting?" How many man-hours of service do you save?

Remember to rewrite an investment only once. The return on investment in rewriting lasts forever. forever .

Focus the question of meaning to specific questions. You have indicated a bunch of them above. Stick to it.

  • "Will we get more value by reducing discarding garbage that we don’t use but still have to wade through it?"

  • "Will we get more benefit from discarding unwanted and unstable stuff?"

  • "Will we get more benefit if we understand this, and not by documenting, but by replacing something that we created as a team?"

You are homework. You will have to confront the following traffic jams. They will occur somewhere in your executive food chain from someone who answers as follows:

  • "Destroyed?" And when you say: "It did not crash as such," they will say: "It has not broken - do not correct."

  • "You did a code analysis, you understand that, you no longer need to fix it."

What is your answer to them?

This is only the first hurdle. This is the worst situation. , .

- :

  • " . , , ". , , , .

, - - .

, , . , .

+3
28 . '08 0:33
source share

, , . , , , , .., , , , . , , , .

, / to-plan, , . - , , , . , , .

+2
28 . '08 1:25
source share

(, 100 ) . , /KLOC? ? . ( ), .

+2
28 . '08 1:28
source share

. , , , , , , , ( , , ), .

, , , , , . , , . () , .

+2
28 . '08 8:57
source share

, " " . :

, , : " 40 - , ". [MI], , , " ". US Air Force Information Warfare Center [DOE], , â„– DOE -AC07-94ID13223.)

+1
28 . '08 2:06
source share

, ...

  • .

, , , .

, , / . , , , , .

+1
28 . '08 2:55
source share

( -) ?

, ( , ), , , , , , .

+1
13 . '08 21:53
source share

( ), , .

0
28 . '08 0:12
source share

. foxpro #.

, ?

. , . .

, . , .

, . , . . ?

0
28 . '08 0:43
source share

, . , , .

, . - , " ..." - . , , , , . , , ... .

GM, , . " " - . " , , " .

0
28 . '08 1:15
source share

, , , .

? ( , ). , , , . ? , .

, - , , , . , , , .

0
28 . '08 1:21
source share

, , , , , , .

, . , , , , , , . , /, . , , 10 , - , .

0
28 . '08 at 1:36
source share

. , , - , . , - , GPLd.

0
28 . '08 2:21
source share

, . " " . , - , .

0
30 . '08 3:07
source share

, . . . (100 + ) . . , .

: (.. ), .

0
03 . '08 19:02
source share
0
16 . '09 20:48
source share



All Articles