When Should You Go Back To The Drawing Board?
Prozzaks asks: "As junior developers, one of the task we will likely be called to do in a company is system maintenance (updating, bugfixing, adding functions to a existing system). I've already had a situation where it was necessary to do some maintenance, and after working a few hours on the system, I realized I was redesigning it from the ground up. The problem is that companies don't want to allocate the necessary resources to redesign a system. What are we to do when we discover code in the companies products that -really- needs a rewrite and management staunchly refuses to realize this fact?" There are times when I can understand the desire to go in and rip out code that you feel isn't operating as well as it could, and there are times when you have to sit back and weigh the benefits of a rewrite against any possible gains. The adage "If it ain't broke, don't fix it," applies here, but there are times when badly designed code that works now, will break later. Under what situations are rewrites necessary, and how can you get management to understand the need if it arises?
Are you really asking Slashdot this?
Rewriting your flagship product is the best way to kill a software company.
Example: NETSCAPE
From almost 100% to almost 0% or less market share in the windows browser market?? Sounds like death to me.
Assuming you have one of those.
If you don't, it means that eventually that huge pile of cruft you are working on will enter either the overbloat or bit rot stage and you need to get the hell out of there.
Good luck,
Jim Burnes Sr. Software Engineer (20 yrs experience)
Actually you should rewrite it in Scheme, then translate the Scheme to Java bytecodes in your head. This will give you a profound understanding of the system from a functional perspective, while not avoiding the low level details.
Don't forget to write a JVM in MIPS assembler then run the JVM on a MIPS emulator written in COBOL.
This design is called the "phux0red" pattered by the Gang of Four.
People always say, "If it ain't broke, don't fix it", but this is not right. The saying should be, "If it ain't broke, and isn't breaking, don't fix it."
That only half-applies here though. The question isn't about fixing (if you interpret this as incremental), it's about throwing it out and redoing things. But if something is breaking---that is, not going to fulfill future needs, or not going to scale properly, or going to present problems---it needs fixed, and that's where this question comes into play.
Sometimes, an existing system is so poorly designed or half-implemented such that doing any sort of maintenance at all would take more time than redoing things. I've seen a couple of these, and the choice seems obvious. You reimplement. Right? Maybe. You need to determine whether you have the ability and resources to reimplement the system. Junior developers can easily underestimate a task, and this can end up wasting a lot of time and effort, which translates into money. Before you even think about suggesting this, you need to be sure you can pull it off, or you'll cause problems for everyone in the future (including yourself).
If you can do it, then talk. Management understands dollars-and-cents. That's what they're there to get. That's what the company is there for. Translate maintenance on the existing system into costing more than reimplementation. This is what they care about.
Don't think of it as a flame---it's more like an argument that does 3d6 fire damage
Indeed, often when I'm doing the incremental rework. I know very well where I want to end up in the end. It's just that ending up there after restarting from scratch is not always feasible within the constraints imposed by real life. What follows may be new to some of us out here, but software that is actually worth a rewrite tends to have active users who want bug fixes and new features now, not 2 years down the line. Maintaining the current version may also be what keeps the money coming in that is supposed to pay for all the rewriting.
I agree that clean code instantiating a good architecture is the max. But almost clean code instantiating an architecture that is actively on its way to become good is still a lot better than one pile of obfuscated dung that only pretends to work, and a pile of paperwork documenting a new and shiny system that didn't get more than half implemented before real life intervened. Of course, some systems are way beyond rescue. When I run into one of those, I too call for a rewrite and otherwise refuse to work on them.
--
Linux user since early January 1992.
Anyway, if you're good enough a programmer to recognise the badness of the old design and come up with something better, the risk of ending up with nice and shiny code trapped in a bad old design isn't all that large, IMHO. If you're not good enough, you're doomed anyway. Even if you restart from scratch.
Also, if you have a working program to start from, or at least one that does at least some things right, gradual changes can be quite easy to apply and debug, even if they're design changes. This has the nice effect of providing a stream of small but nice successes that both keep you going and can help to convince management that it's worth investing some more and that you are capable of dealing with that. You do have to be willing to compromise and eat the cake in somewhat smallish bites, though. Don't shoot for the big ultimate design from the start. Instead, go for something that is 1) better than what you've got; 2) reachable; and 3) a suitable starting position to move closer to your ultimate goal at some later stage. Extra advantage: if, for whatever reason, you have to abandon the rewrite before it's done, your legacy is much more likely to still be usable.
One somewhat nasty but potentially also very big advantage is that the gradual approach can help to get the work done even if management is all PHB and doesn't recognise (let alone have) a 10 foot clue if it hits them in the face. Basically, you don't have to tell them all the gory details of what you're doing (which is not the same as lying about it). Of course, not all company cultures will allow for this.
I've done all this several times, both at work and in my spare time. So far it always worked.
--
Linux user since early January 1992.
"To ask is to seek denial" as a teacher of mine often said.
DCMonkey
Ok replying to myself sucks but just to illustrate a point where you can go from either fixing things or rewriting things.
/. has a distributed db backend). So, with the limited resources, something had to be done there. Switch to PostgreSQL (7.1beta3 FYI, it's fast). This involved a good day rewriting some core modules (I like OO stuff) and another few hours dumping data out and restoring it piece by piece. (so I made some table changes too).
I wrote a rather sizable bunch of mod_perl modules, interfacing with a mysql database to keep track of a partnership system (pay-for-clicks/signups/whatever). Now, the company that runs it is quite small, and has limited resources (one db server, one web server, that's it). The first week, everything worked fine. The second week, everything still worked fine but it got slow. The third week, it took so long to load a page that you could get yourself a frappucino at the nearest Starbucks.
Was it a design mistake? Not quite, it had more to do with MySQL not being able to deal with 50+ queries per second. (AFAIK
That's a pretty clear-cut case where code that isn't broken is in definite need of rewriting.
If you encounter code like that, and you are confident that you know what it's supposed to do (learn the code first, then fuck with it - don't fuck with it and then learn about major fuckups.) then you go and fix. If you don't know what it does, or what it's supposed to do, it's best to leave it alone for a while.
Now can someone pass me my caffeine IV? My 48 hours-of-being-awake are catching up to me...
There is no sig...
Or the H1B that touched it last.
:P Doesn't mean us foreigners can't code :)
Bah
There is no sig...
Amen to that. Thankfully I'm in a position where my boss - he's tech-savvy but don't ask him about databases and programming, although you can explain algorithms to him and he'll get what you mean - actually lets me do what I think is best. That's one of the first things I told him when he hired me; "you hired me to code, and solve problems. so let me code and solve problems, don't get in my way, don't drag your feet, and if I say it's broken, that means it's broken".
:P)
I got that way after too many bad experiences in $VBC. I guess on an experience level I'd be considered a junior programmer still; since there is a lot of things I have yet to learn, but dammit, I do know when something's broken or not, or is in need of some work to either make it work better, faster, or just make it more readable so the maintenance bit is easier.
(Ok so this topic is something I can get all fired up about.. sue me
There is no sig...
They're not paying you to make the code pretty - they're paying you to add features, or eliminate bugs. That being said, it is often the case that ugly code can severly impede your progress. This is a perfect time to refactor to make the code better. Refactoring means changing code without changing the behavior of the code, only changing the organization. See the refactoring book (by Martin Fowler) for more information.
****Gfx Scrollbar Special case hit!!*****
In my first job, I was in charge of some mortgage software that had been around for over a decade. Compiled in MS C v6 for DOS (this was in 1998-1999). Horrific code. I would have loved to have rewritten it, with or without management support (there's a whole story there). The thing is, the database and windowing software that were the basis of the program were more broken than the code itself. I would have literally had to redesign the entire application from the ground up myself, for a program we didn't even sell any more. Needless to say, that didn't happen.
Even if the code is bad, if the problems are deeper than that, any rewrite will be a waste of time.
Refactoring is invariably a technical decision. It does not change the behavior of the program, and it allows us to work faster. There is very little associated cost with refactoring, assuming you build tests to back up your assertion that the system's behavior will not change (bugs and all) while refactoring.
Now when I say Refactoring, I'm not talking about "heads down, that's all I'm doing". I'm talking about Martin Fowler's view of it -- every day, a little bit at a time, to clean up the code and make it more readable / maintainable, while you're adding features or fixing bugs.
I think your exposure to development teams might be rather limited to think that there are always "maintainers" and "designers", and that maintainers are lower on the rung. I've seen two situations to counter that: one where the maintainers were *deliberately* the more talented bunch of programmers, since they have to deal with tougher situations than those with a "blank sheet". The other situation (far more common) is that the core coders also do the maintainence until they have a replacement.
Management does not hate refactoring, if it is done properly. They hate *rewrites*. A *rewrite* requires management decisions because it is in the realm of business - it is about throwing out the existing system. And it rarely works the way it's supposed to.
-Stu
Last march I began work for a fairly Large ISP's web-app development department. I was brought on as a senior developer, due to my experience with web apps and development in general, and was also considered the 'problem solver' of the group.
Within days of being Hired I was asked to work on a project I will call 'NOX3' (changed to protect the parties involved from litigation - Seriously!) - this project had been ongoing for almost 2 years by the time I was brought on. All of the original developers had left the company - and just two months before my arrival a 'needed' type of join had facilitated the change from utilizing mysql to Oracle as the backend DB.
As most of you may or may-not know, Oracle can perform very well - when the DB is archetected correctly with its relationships and indexes. As it turns out, we had seen a 260% DECREASE in performance switching to Oracle: this was because the developers involved (by the time the switchover took place, an outside development company was also involved) did not want to rewrite the hundreds of queires used by the system and so copied the table structure over to oracle with no schema changes, no added indexes, or anything. Due to the 'flat' nature of the schema, table-scans were common-place, leading to horrible performance with the full 800k+ rows in the main table. Linux's max-file size (2GB at the time, thank god for 2.4!!) actualy held us back by forcing indexes and tables to be spread over multiple files, which also affected performance...
Anyway, I'm getting off the point. As I said, within days of being hired I was put on the team of developers working on the project and told to 'see what could be done, a silver bullet would be nice'. Well, the deeper I dug, the more I realized a silver bullet didn't exist - the app was horribly archetected, badly (= none) documented, uncommented (180k lines of code, only 1k lines of comments!!!!!), hampered by the DB schema and even by the choice of technologies used to implement the system. To add insult to injury, the team of developers (now 'mine') inside the ISP were just running support/bugfixing, because the customer was doing field tests of the 'beta' (not my choice of term) copy of the app live, and the external development company brought in to consult was working on adding features (to the live beta app, mind you).
I told my managers that the project was a write-off at best, and that if they ever expected to get near the performance the client wanted ( we were two orders of magantude two slow), and support the number of simultaneous users they wanted (5000 active users, with peaks of 15k+), we needed to start a re-design imediatly before things were even further behind schedule. (the app was 13 months late... I'm not kidding)...
I wasn't listened to - the manager nodded his head and passed on the message, but nothing happened. So I started giving him reports with all of the horrible things I was finding, things he could show his managers - they didn't listen to the reports. So for two months I fought just to get permission to spend actual company time running benchmarks/tests of the system to prove my point... I ran the tests and boom - the system Crashed (not slowed down, actual crash) at 48 simultaneous users - crashed so bad it took down the machine the app was on (but not the DB machines). Finally I had my boss's attention, my findings were vindicated...
We never got to do a rewrite, instead the project degenerated into legal wrangling complicated enough to confuse OJ's lawyers. The consulting company claimed it wasn't thier responsability to comment on the quality/capability of the app - just to add features - meanwhile my company claimed that they should of performed 'due dilligence' in making sure the app could perform as required, and they should of opened thier moths way before I blew the whistle, meanwhile the customer went after both my company and the cunsulting company, and my company brought in a second consulting company to verify/audit my findings and gather evidence (this took 4 months, meanwhile we sat almost idle).
My team was dismantled - all of the developers on the team (except for myself) were hired with specific skill sets to work with the technologies the app required, and thus weren't needed any more (this was 2 months after the 4 month audit was completed). The original manager who started the project was fired for 'other reasons', and my manager, who came on board just 4 months before myself, was also let go. All of this firing and such took place 8 months after my hiring. A week after my hiring I had determined (and was already telling my manager) that the system needed a complete redesign, and it would take 6 months with the right design and current team, to do it right (no contact with the customer would of been allowed, along with no testing, we needed six-months of heads-down coding time). Instead of listinging to the person they had hired as thier 'problem solver' and senior developer they drug thier feet and then dismantled the project, but paid everyone for 8 months work along the way.
So which makes more sense, 8 months of paying everyone involved just to end up cancling the project and then get into costly legal manuvers, or six months of paying them to deliver a working app to the customer, late (which, surprisingly, the customer was fine with, as it turns out - time wasn't the issue, functionality was)? I don't claim to understand it, and I still don't know why they did what they did - my point is, asking for a re-write can be like wishing to win the lottery - the powers that be can work against you.
man is machine
Well, how about a hard, real-world example. Granted, this is a "toy" by many standards, but it was definitely a case where I applied the 50-50 rule. On the plus side, we do value documentation in our shop.
Some of the code I was inheriting contained this gem:
short *arr_ptr[8];
for( j = 0; j < 8; j++)
{
arr_ptr[j] = (short *) malloc(1 * sizeof(short *));
if (!arr_ptr[j]) printf("\n Unable to allocate space for ln_buffer\n");
if (!arr_ptr[j]) exit(2);
}
for ( i = 0; i < ish_y_dim; i+=2)
{
iptr += 2*ish_x_dim;
if (iptr > xend) iptr = xstart;
ptr = iptr;
for( j = 0; j < 8; j++)
{
arr_ptr[j] = ptr;
ptr += ish_x_dim;
if (ptr > xend) ptr =ish_image;
}
}
Now tell me, why's that malloc() there and where's the memory going? That entire first loop has no reason to exist! As it was, the rest of the code was also overly complex and none of it was doing what it really should be doing. The stuff it was doing it was doing in a rather tortured way.
So, I threw out that function entirely and wrote a much cleaner new one. Right now, I've got some other code I've inherited that's a bit larger than this, and I really, really want to rewrite it. Fortunately, though, I'm not being asked to maintain it -- just run it. Since I don't have the time to rewrite it, and I'm not charged with maintaining it, I think I'll just let sleeping dogs lie.
--Joe--
Program Intellivision!
That's a sane way to do it. Doing things this way now has a buzzword associated with it -- "refactoring." I welcome the trend to actually study how to maintain programs instead of just writing new ones, because, almost by definition, you will spend a lot more time maintaining a useful program than writing a new one.
If it looks like its gonna take me at least as long to understand whats there as it is to rewrite it, I rewrite it.
Frank W. Miller
On the other hand, overzealous change control can lead to "big ball of mud" software over time. I think it is totally reasonable to refactor / improve code as you fix a bug or add a feature.
HOWEVER, that is subject to being able to *test* the results to make sure the software produces the same results as before. If you can't test it, you have no way of know that you didn't break something - in which case it does make sense to make the minimum possible change to fix a bug/etc.
I don't value a person's opinion until he or she learns the basics of grammar, spelling, and other elements of good writing.
Your condescending tone makes your little error stick out like a wart on a bald head, pal. (Otherwise, I'd be too polite to mention it.)
Everything should be made as simple as possible, but no simpler. -Albert Einstein
TEH SALSHDOT SUKX0R-B0T0RZ!!!!!
I've often found that when bug fixing, you can make your bugfix incorporate some improvements to the current design without too much hurt, but you do have to ensure what you're doing is limited in scope, otherwise you may have to retest the whole program.
:-)
Even if a program looks revolting, in the main it is better to live with it rather than fully rewriting it. Remember if you rewrite it, then in theory you have to redesign, recode, TEST!!!, run pilot trials etc, all without interrupting the end users who are probably earning the company the money that you want to spend on the redesign.
Code for consumer products is even more fraught with difficulties; if you recode something and get it slightly wrong then you risk a product recall. Also consumer products generally only have a short lifecycle; if the product you want to redesign is out there its probably obselete, and therefore spending money on recoding is a bit pointless; you should wait till you get promoted to senior developer and work on the next generation, where a cleanup of the code can be absorbed more easily.
Donte Alistair Anderson Roberts - hi son!
Karma: Chameleon
I'm currently in the process of rewriting a stats processing facility for a site I run. In the past people would come to me and ask for numbers and the whole thing (based off of korn) started becoming a steaming pile. New reports would need to be coded and it would just get added on without any attempt to optimize the code.
As soon as I saw this happening, I just said fuck it and started recoding everything that had been written. I didn't talk to management, I just did it. Granted your project is probably a lot larger than what i'm working on, but if it's really needed you have to go ahead and do it. I moved from a shell/perl/textfile mess to a database backend and i'm going to be adding support for realtime stats. I work on this in my own time and without management's approval. Sometimes you just have to go balls out and drive things to respectability.
...or you'll be hitting the street. Immaturity prevents the junior programmer in this case from realizing that computer science purity is NOT the same thing as economic viability.
:)
Case in point: any Microsoft product.
If you are given a task of optimizing a routine or fixing an array over run - do it. That is your job.
I am betting Defect #12332 in the bug queue doesn't say "redesign entire system (by person with 2 years professional experience)."
Senior programmers have the job of revamping the design.... managers have the job of deciding to do it.
Remember, there are people at your company who are buying baby food with the pay check that this "horrible" software is generating.
This isn't to say "keep your mouth shut and toe the line" - definately point out where improvements could be made - but when given a task stick to it.
Most junior programmers start such rewrites b/c they haven't taken the time to understand the code.
I am very small, utmostly microscopic.
There are no buzzwords in computer science. I know no term in computer science that has no real meaning and is constantly used by people who want to sound important. (Sadly, sometimes terms have real meaning and become pseudo-scientific babble nevertheless. Take...quantum physics. I've lost count of how often I have heard people without any clue draw analogies from something-or-other to Heisenberg's uncertainty principle <sigh>.)
I think you're confusing computer science with software engineering. (And yes, I know that the former is no real science and that no engineer would call the latter engineering.)
An impression from long ago that a lot of problems come from trying to rescue bad code.
Rewriting is better if you can dominate the design of the old system (much easier said than done). The old system with its cruft has the advantage that it has been tuned, that the bugs that matter have been squashed at the expense of bugs that do not matter. Most likely, by now, nobody knows or understands what the old system is or should be doing.
If (when) you rewrite it, you MUST understand it better than the original authors plus the accumulation of bug-fixes. You do have one thing going in your favor. Almost certainly the old system is wasting a lot of resources (including or especially program complexity) attempting to solve non-problems. If you can identify several of these, you can un-level the playing field enough so that a rewrite is feasible.
Nope. He's right. You can replace a bad design completely by a succession of tiny incremental changes. Mother Nature has been doing it for a few billion years.
Rule of thumb (from 2nd generation mainframe days)
If one programmer can do it in one year, two programmers can do it in two years.
>>If by deleting code you're adding functionality, then the system needs a rewrite.
I haven't seen that before, but that looks like the simplest and best test imaginable. The situation happens because code that has been added to increase functionality has actually had the opposite effect. In that case you stand a very good chance of understanding _everything_ the system is doing that it should be doing, which is the sine qua non for redesigning something.
It can be fascinating to watch the programming go away and the functionality go up. If you haven't seen it, you wouldn't believe it.
Ugly. Extremely effective criterion for changing something.
Rewrite it, but do NOT change the real system. One of two things will happen. Most likely, you find where the cans of worms are, find that the existing system is more complex and complicated than you thought and duct tape and chewing gum is the answer. Possibly, the rewrite is definitively better than the original. Only then should you or management commit to doing something that maybe shouldn't even be started.
In many cases, the best way to understand something is to program it. In many cases, keep the understanding, dump the program.
Sucker bait. "than I" only looks like "I" is the object of a preposition. ....
... better wordsmith than me is a wordsmith
... but the meaning is lost.
The real trick is to distinguish between code that is bad and code that you think is bad.
[usually because I'm not used to how it goes about solving the problem]
It's somewhat like judging German grammar from a knowledge of English grammar.
Substituting "read" for "figure out" glosses over the difficulties of understanding something foreign. It's just not that easy.
Finally, this illustrates a problem with rewriting something without carefully looking. It's far too easy to lose the original purpose of the system in the process of cleaning up just what you understand. The parent post is not clean and smooth-flowing, and maybe that is part of the point (s)he is making. It would take a far better wordsmith than I to clean it up without losing its value.
That's not what stepwise refinement means. The term has a specific sense that was introduced to software development by Niklaus Wirth's paper in the Communications of the ACM, 14(4):221--227, April 1971, "Program development by stepwise refinement".
Stepwise refinement is a procedure for refining a design, from a high level design that closely resembles the requirements, progressively down to a low level design that resembles code. It is not related to refining a code base by rewriting parts of it. You will have to find a different word for your maintenence programming style.
s/better wordsmith than I/better wordsmith than me
It is a given that you should always maintain the ability to roll the system back to any earlier revision. Doesn't matter if it is split up over a network, etc. If there is no version control in place, that would be a good project before one embarks on any kind of rewriting. A project that is not under version control is playing russian roulette. And it is not just a matter of implementing the version control technology; you need to get everyone who edits the code to use the system properly and consistently. It's worth it!
He called it "The Second System of Man", and one of the tenets was "The Second System is Fat and Slow".
Buy it at Barnes & Noble if you like.
+++OK ATH
My own personal belief is that the desire to not redesign is far more powerful and needs to be guarded against far more than the desire to redesign. However, you need to keep backup copies of everything in case you make a mess of things. I've never understood why some programmers just start making changes to their source without making sure they can get back to where they started.
As for selling it to your superiors, well, if you're the programmer, it's properly your decision, not theirs. You don't ask them for permission to do it, you tell them that this is what needs to be done, or maybe you tell them that this is what you did. You're the only one who is in a position to tell whether the least effort approach is to fix or replace, so act like it.
Sure, it's usually a good idea to consult with people of differing perspective and varying experience before taking any drastic action, and you must consult with the other programmers any time your changes might affect what those other programmers are doing, but if you're the programmer, you should have the final say in how the programming goes.
If you can't make that stick, and I haven't always been able to, you can always use your coffee break time, lunch hours, the odd evenings, and sometimes weekends to do your rewrite or redesign as a kind of a "skunk works" project. I've done that a time or two, but you must guard your time off jealously. If they already expect you to work evenings and weekends, then it's probably best to put your CV out. In this job market, there are other places to work.
I am a programmer, and as such my attitude is and always must be:
Rewrites are always necessary.
Management must get out of the way and support it at all cost.
Only then will Good Code rule the world.
--------
Yeah, I'm a Mac programmer. You got a problem with that?
-- thinkyhead software and media
Andrew Semprebon EQ Systems Inc.
This is the classic stovepipe system anti-pattern, and is caused when your code has too many intertwined and circular dependencies. When this happens, it's impossible to even predict how many areas will be affected by a given change. The code has reached the point of no return. (Note the original intent of object-oriented programmed is to reduce dependencies between varying systems.)
Of course, what most companies do that this point is hire a Mongolian Horde of programmers to fix things by brute-force, aka the "Warm Bodies" anti-pattern. By then, it's too late. Leave.
Unfortunately, as a junior developer, you probably shouldn't be making these decisions yourself; you'll only anger people above you. If there isn't a culture of refactoring when necessary, there's nothing that can be done. It must either always be there, or brought in and bought in from the top. Sadly, most PHBs do not understand this. I find it laughable when a PHB will hire 40 people for 4 years gang-banging the code, instead of having 3 or 4 smart people send a year refactoring.
I can explanate how to administrate your network. You must configurate and segmentate it, so it can computate.
The initial design was done by a moron, who is just out of Uni and who read too many UML design books, but never seen/written a real program. The code was
- over engineered
- threaded unnecessarily
Ah yes, all other code was coded by morons. Strange how anything ever works really.
I got to [...] maintain it [...] I have learnt
- a lot of Java thread issues
Maybe you just learned better to understand Java threading issues. It's surprising how many times you look at something that's "really stupid", but once you've "fixed" it, the fix turns out to look exactly like the original did.
At one site I worked at there was a report suite which was known to be producing wrong numbers - the programs were demonstrably broken, there was no dispute about this. The trouble was that the end users (you know, the one who are actually paying the bills rejected the the corrected reports and insisted on having the wrong ones back as they 'preferred the numbers the old one gave'. Go figure..
----
I hereby inform you that I have NOT been required to provide any decryption keys.
While working on that crufty old component, I decided that the easiest fix would be to add the extra functionality on the client side. A few active modules downloaded from the web would fix this in short order. The result would be an easy to use and maintain object oreinted visual client.
If he buys this, start drinking lots of beer and send out resumes. You won't want to be around to maintain the results any more than anyone at your company has stuck around for the past 12 years.
Having found myself at numerous entry points in development cycles, I would suggest anyone in this situation give Anti-Patterns a good read. ISBN: 0471197130 This book will give some fabulous insight into this exact topic.
Don't get cocky. Just because you think you can rewrite the code, doesn't necessarily mean you can do it any better than the original software developers. The one thing I find badly missing in the s/w world is common sense.
Ignoring new development (e.g. replacing an application with a new version with different functional specifications), and focusing on the maintenance process (i.e. fixing identified errors in a program), what is the minimum possible change to a piece of code? Probably correcting comments (no functional impact, one hopes!) Examples of changes which incur progressively greater impact (and this list is merely a subset) would be:
The further an item is down this list, the longer it usually takes to make the change. So the decision becomes a value judgement: at what points does the utility of making the change exceed the cost of making that change?
At the extreme end of the scale we have the quick fix or quick hack which takes only minutes to implement but has an obvious benefit. At the other end there's the system rewrite, which might take months yet provide only a nominal improvement over the existing system.
As a developer and a manager I expect code to be of good quality whether it was written by the maintainer or not. Bad code (the stuff people want to rewrite) is code which falls over, gives wrong results, is not robust or is too specific (i.e. similar to being not robust, will fail erroneously given slight change of input conditions). Bad code is an indication the programmer was doing their job poorly.
When it comes time to fix bugs, I expect the maintainer to understand the minimal change required to fix the bug, and also to evaluate the quality of the code which caused the bug. If it's bad code, it should be rewritten. Of course there's still a value judgement in here; I would not approve a rewrite which had negative utility.
There's also the matter of pride in doing a good job. I take pride in writing good code, and I expect my team to take pride in the quality of their work. To allow shoddy code (even somebody else's shoddy code) back into production is contrary to the spirit of pride in one's work.
A prevailing attitude of "that code's bad but we'll only fix the big error and leave the rest of the bad code alone" must also imply, even subconsciously, that "bad code is acceptable" and this may reduce the quality of newly written code.
So in summary my advice is, if you wish to take pride in your work and become a craftsman rather than a hack, you should ensure that only good quality code leaves your hands. If your company asks you to bend (or abandon) your principles, make sure they have a good reason for it. Learn how to write good code. Learn how to analyse code so you know exactly under what conditions the code fails, and thus make your own judgement on whether the code needs rewriting (and which parts need rewriting).
That's the funniest thing I've ever heard
I hear ya! I once had a huge back end C++ app that would crash about every 17 hours due to humongous memory leaks. Solution? - well I could have run purify and tracked down the leaks, tried to fix them, so and so forth. Naaah, I just slapped together a few lines of ksh that checked for a core file every 10 minutes and then re-start the app if one existed. Problem solved.
My rule (I've been doing this for 15+ years): Try to evaluate how much it will cost to keep the crappy code working over the next 12 months. If you can spend less than that in doing the rewrite, it is probably worth it. Also, talk to an employee or senior contractor and see what they think.
Wasted almost three years of potential market share on their rewrite. Sure, maybe Mozilla's a better product now, after almost three years, but was 4.0 in such bad shape that they had to rewrite the entire thing? That's where I feel you should ask yourself in rewriting your product. Would it be faster to rewrite a particular function of the application? I'd be much happier with Netscape 5.0 or 6.0 with a rewritten rendering engine than a whole new interface that is arguably slower. So, to get back on topic, see if there is a particular function that can be rewritten that wouldn't take as much time as a full rewrite.
And don't call me anti-Mozilla, I'm using Mozilla 0.7 to post this. :)
Why is it that the proponents of "one nation under God" are so eager to get rid of "liberty and justice for all"?
9 out of 10 times you are prob. right that the code is junk and in the long term needs to be redone but .... 1 in 10, the code is quite good, it is just using some technique or design pattern that you don't understand. Make sure you are not in the second case before you start hacking.
I wonder if the only reason this was moderated up is that the subject line is so attention getting.
Care about freedom?
I'd rather be lucky than good.
Things run smoothly for a time and everybody has been saying "It ain't broke" and therefore, there's no need to fix it. But over time new requirements will emerge that the original design is no longer suited for. You want to scale it up to handle twice the volume; you want it to run twice as fast, you want to add in new network connections; you want to store more data than it was originally designed to handle.
At some point, a system or piece of software that WASN'T broke last month IS BROKE today. Recognizing when that line is crossed is critical and somewhat subjective. It is difficult to get consensus on exactly when that happens. A clear example of this was the Y2K problem. If nothing was done there WOULD have been severe problems. Management and software people and hardware people KNEW when that line would be crossed ahead of time and STILL a lot of organizations kept putting off the effort needed to fix the problems. It was a given that "not broke" code as of Dec. 31, 1999 all of a sudden would most definitely BE BROKE on Jan 1 2000 and right up until the bitter end people kept putting off the repairs..
So what if it's not going to work in 20 years? It works today so don't worry about it. So what if it's not going to work in 6 years? It's working now so leave it alone. So what if it's not going to work in 6 months? It works now, doesn't it? Etc., etc., etc. It's an example of inertia in the decision making process. It applies to large corporate departments and government agencies. It also applies to you alone, sitting at home wondering if you should buy another hard drive or whether to just bite the bullet and buy a completely new PC. It's a subjective determintation and as such, it's not always cut and dried. Maybe you don't have the cash laying around to buy a new box because you had to get a new muffler last week. Maybe you do have the cash but you don't have a backup system big enough to handle the extra critical data. There are many reasons why you might choose the band-aid approach. At some point, the whole thing will collapse and then you have no choice. Unfortunately, there are no easy answers. You've got to justify it - whether it's just yourself you have to convince or someone up the food chain. Why should it be done and when is the best time to do it?
That doesn't make the reason relevant anymore.
Why is your computer keyboard QWERTY?
Because a typewriter was
Why was a typewriter QWERTY?
To slow your typing down
So why does your typing need to be slowed down on a computer?
good eatin', too.
Having just finished reading the book I have to wonder how much things have changed since the adoption of high-level languages, which he mentions as more of a new toy/accademic curosity than a real-world tool.
One would only think that using HLLs would allow people to more effectively interface with and understand somebody else's code.
Getting back to the original article, it seems to me that rewriting the whole thing from scratch is often one's first instinct, as something that's sprung entirely from your own mind is always going to be easier to comprehend and modify than something you've had to learn. Two important questions come to mind tho' : Will it be more effective for you to rewrite than to modify the existing system? Will your version be easier for the next guy to maintain than the existing one?
my sig's at the bottom of the page.
Slap another layer of cruft on that bad boy and go snowboarding. It's not like you are going to be the one supporting that pile of spaghetti, right?
Information wants to be anthropomorphized.
If you can see possible errors that could foreseeably happen then yes, cover those conditions, make the code more robust. But I warn you make sure you are preserving all of the functionality and that you're just not introducing more bugs. It is sometimes very difficult to do it right, and you need some really good testing of old vs new code to make sure the new code is doing what the old code did.
And
1 & 2 are late payoffs, 3 is important to become a better coder. Also, code reviews help it so that everyone starts to code the same way (visually) which helps a lot with comprehension.
(One of the reasons I changed to my current employer is that they are really cool about writing good, solid code. We also have a fairly good code review process in place as well and I'm better off for it.)
For me, one of the greatest accomplishments is to take code and be able to add functionality without breaking other, older code. Stealth kung fu ninja coding
While you're at it
depends on the importance of a system. The dollars spent maintaining a system that has low impact and few users should never exceed the importance of that system. On the flip side - if maintaining an important high impact system requires certain modules be re-written in order to "clean the bugs", then so be it. Any diversions or impacts should be evident during the code walk throughs with your technical project managers.
If you have high dollar programmers maintaining uselesss or un-used systems -- their is a budget cut just waiting to happen. (kind of like installing a sprinkler system on the lawn of a condemed building...)
(+1 Funny) only if I laugh out loud.
Well in the case taht led me to post on /. the interface doesn't even reflect what the program realy does! It consisted of 28 PHP files that accessed data stored in text files. Among those 28 files, not one, NOT ONE function was to be found! Well I had the chance to be able to talk with the user for witch the program had been designed so I was able to get a general idea of what it was suposed to do.
'Nuff said.
sulli
RTFJ.
I'm the Senior Engineer who's managing this very situation. Or, more precisely, two situations, one where we've replaced existing code, and another where we've kept ugly code.
In the first case, my company has an existing product based on old technologies (Borland OWL, DLLs) that needs to be updated for new environments (Linux) and technologies (COM+, CORBA, etc.) We pulled the business logic out of the old code and re-wrapped it in more modern and portable form. In other words, we kept what worked, and only replaced the parts that had no place in our new products.
In the second case, we purchased a powerful library from Someone Else, including full source-code rights. This library is some ancient K&R C code that was poorly wrapped in C++; it stinks aesthetically. No comments; terrible formatting (and I'm not that picky!); strange code conventions that are common in C but dangerous in C++. Overall, a mess --
BUT THIS UGLY MESS WORKS
So, other than adding a few new features, and fixing a couple of bugs, we've left the morass alone.
You won't find any hard-and-fast rules about when to replace existing code. It's a matter of judgement, probably best left in the hands of experienced engineers who've been around the block a few times. Alas, management politics, schedules, and technical skills will influence the decision.
My basic rule: If it ain't broke, don't fix it. I might wince at at a piece of code -- but my customers care about how well a program runs, not how pretty it is.
--
Scott Robert Ladd
Master of Complexity
Destroyer of Order and Chaos
All about me
Unstable code produces multiple defect reports in short order, and the reports just keep rolling in. One programmer's bug fix will unfix the work of another. Code of this type has to be rewritten or it will never converge on production quality. The programmer tells the manager "This will never work if we leave it like this!"
Trying to tell a manager that you are going to save them time in the long run is certain to fail -- and rightly so. Code that misses schedule often has no long run to worry about. Tell managers that without a refactoring, the code is unstable now, and that not fixing it will leave them with egg on their faces immediately on release.
If you are a senior programmer who designed the interfaces, classes, and data model of a subsystem, you are in a good position to tell if an implementation of your design is workable. The best time to tell, though, is in a walkthrough before major unit testing. Once software gets past unit testing, a manager will mark it "done" and any rewrite will be a major source off annoyance.
One of the benefits of the Y2K bug is that it forced many companies to get rid of outdated, out-of-control systems, and replace them with something maintainable. Perhaps we need a YKKII scare to help us clean up the rest.
Donate background CPU time to fight cancer.
If you were to re-design a product every time you find a better way to do something, you would never be finished.
Take for example a website. If you were to redesign the layout everytime you had a better idea, you would never have a finished product. When designing something such as a website, finish with what you have. Get something that out there that works, then redo it.
Just make sure it's not shoddy though. Otherwise it won't be accepted by the consumer and any idea for a re-design would be practically put to it's death. You would lose way too much of the customer-base if the initial release sucks.
I have been in this situation before. The code is really REALLY bad and was written by the village idiot the first time, and really needs a rewrite to get rid of the incredible amount of bugs. What you do is this:
1. Try to convince management that it needs a rewrite
2. If that don't work, go work for another company! Fuck em! Why would you want to work on such shit code all the time when management don't want to fix it?
I had a similar project, and waited until we switched the backend from SQL Squirter/NT to Oracle/Solaris to make the big changes. Difficulty in maintenance is not usually enough justification for management.
that you must turn five pages of crap and turn it into a single useful page of legible code. I had to do this one time on a demand service call.
I see it like this: If you have a messy desk, what's the use of cleaning only a small part? You made a clean spot and the rest looks like shit. So be prepared to spend the time necessary to clean the rest, or don't futz with it.
if( rebuild.benefit > rebuild.cost ) { rebuild.begin(); } else { legacy.patch(); } porting this to your favorite language is left as an exercise to the troller.
You will never convince management types that the code needs rewriting unless it causes them specific, identifiable, monetary problems. One example is an expensive lawsuit that could arise from malfunctioning code (only applies to mission-critical applications). Another is the conception that users or clients will be dissatisfied with the end product and stop buying.
If you can find a case for either of these, or any other "money problems" that could arise, it will provide your best chance at getting the opportunity to rewrite the code.
std::disclaimer<std::legalese> sig=new std::disclaimer; sig->dump(); delete sig;
Fight code ownership rules that keep you from doing the right thing (TM), unless you really can place the blame on the programmers of other modules.
It can easily happen that you will discover that this doesn't work because the old thing really did a lot more. Then try to find out which features are really needed and rewrite only that.
Or write a 20 line script in perl which does the same job :-P
Trying to play wise man, hope it helps someone.
I'm still trying to figure out what people mean by 'social skills' here.
and most misunderstood code is not well documented ..
I'm still trying to figure out what people mean by 'social skills' here.
Yeah, and look where it got us. You push a person with half his weight and unless he's expecting to actively compensate for it, he falls over. Pshaw. /that/.
"incremental changes" only hack a solution into working, such as Humans, but result in a design that on a basic level could possibly be much better if you knew from the get-go where you wanted to end up, and designed around the best implementation of
a company system is usually this
...
1-a database
2-running on a network
oracle can do easily all sorts of forms and report and almost anything else
so what code are you guys talkin about!!
You can make a complete system with only
knowledge on sql, pl/sql and maybe a scripting languague like Ruby or Perl
so heh !!
sheep for the sheep human for the human i just wonna keep my soul alive
To get management to listen, interpret everything in terms of cost.
Make some man-hour estimates. Compare sifting through spagetti code and applying endless patches vs a clean rewrite.
Project the cost that would eventually go wasted when existing technology becomes obsolete.
Be creative; don't limit yourself to cost CONTAINMENT. Paint a doomsday scenario on maintaining spagetti code and give estimates on cost PREVENTION.
I came upon this situation at my workplace. I am a web developer. We hired a contractor to write a newhire system, and he wrote in ASP. It kept breaking. Since our company is Linux-based, no one knew how to fix it. So they asked me to rewrite it.
You'd be amazed at how many nuances there are to a given application. I rewrote it in PHP. But there were things I was missing, and features I wanted to add. Then, when I finally released it, we found several bugs. Some of those bugs never got fixed, since we have moved on and no longer use it. there were things that were never added; features that were not there.
You can learn so much by reading someone else's code, even if it is just to see what NOT to do! And even if it is just to say, "Hey, I can do that better!" MANY times I have gone to the PHP ResourceIndex to download something and the only thing I can say after I'm finished is, "Wow, I could have done it better." But a few times I have been introduced to simpler ways to do things and easier ways to implement my code.
Bottom line: There are things that will bite you in the @$$ if you rewrite from scratch. There will be bugs. There will be a 1-6 month development cycle (depending on the complexity of the code.) And there will be features missing, and if you implement it, guess who gets blamed...
Now, that's not to say that you should not rewrite it. It is to say, "Be careful." It's those little things, like "I used to be able to right-click on this..." that will get you in the end.
Good luck! Whatever your choice is, RESEARCH it well and TALK IT OVER with your boss and/or anyone else who has programming expertise at your company. Know what you're getting into. Plan out a feature set (it will have THIS feature in v1.0, but not THIS one.) Study the old code, and find as many volunteers to bugfix your new code as you can. Above all, if you don't have to rewrite the whole thing, DON'T. Even tabbing out the code can make a huge difference. You might want to start with the small stuff and go from there.
I am amazed at how perfectly this article dovetails with this story. Joel has a long, reasoned, and compelling essay about why code should be reused instead of rewritten. I suggest the original poster (and the rest of us) take a look.
My Greasemonkey scripts for Digg &
I was once working on a piece of code which required an "enhancement" modification shortly before release. The change to the user was minor, it should have only taken a couple of days. The code in this area, however, was so convoluted with so many hidden dependencies that I literally did not know how to change it. It was so fragile that I could have no confidence that any change I made would have the desired effect. When we approached my manager with the classic "It needs a redesign" argument with not much to back it up aside from our opinion, he rebuffed our request pretty quickly. When I (very honestly) phrased it with the terms "no confidence in my own changes" he realized that we were pretty serious. The change request was flagged with a two-week lead time as opposed to the one day it should have been. Incidently the change was never made, and the code remained the same.
To summarize, assess risk vs. payoff as best you can and articulate it well to you manager. This will result in the best decision for the company.
-B
Not that this wasn't entirely predictable.
My mother tells the story of when she was working as a lobbyist for NRECA.
They were working on a bill to pass some tax code, and it fell on my mother to actually write the language. When she was finished with it, it was ugly and barely readable, but it worked and fulfilled the objectives of the bill.
The people she was working with were, to put it lightly, horrified with the tax code she'd written. She encouraged people to try to make it prettier, but nobody could figure out a better way of saying what the bill needed to say, so they eventually had to go with her language.
The bill eventually passed, and the language used in it was eventually used in several other places. To this day she still gets calls from friends that have run across something derived from her 'ugly' language that could not be improved.
The moral of this story is that perhaps sometimes there really is no way to rewrite it to make it better. Going into a redesign might sound like a good idea, but actually doing a redesign and a rework might be useless, and produce something just as complex and inscrutable as the original.
And, sorry about that, but it's not decision to be made by the geeks themselves. They have to advise and wave the red flags but no more. It's not also a light overnight decision.
I saw the case 3 years ago in a video streaming company. Their capture board was ok though really not great and quickly going obsolete, but they had a great software, very stable under Win95, Win98 and NT (quite a feat !), and very happy customers.
Problem was : the software was essentially 5 years worth of patches, patches over patches and hacks over patches of patches and
- Upgrading the hardware big time and rewriting the software from scratch ? Big investment, lot of uncertainties. Pissing off the customers with a freeze on the old code while the engineers work on the new one. High risk for a tiny company.
- Keeping the current software as is, making the new hardware perfectly compatible with the old one and cleaning the software bit by bit over time ? Result : a bloated hardware, lots of delays, and, ultimately, loosing the cost/performance race and quietly withering away in oblivion.
They wavered between those paths for nearly 2 years, a huge draw on employee morale, and more or less ended up with the worst of both worlds. There's still a chance they survive but
Morality ? It's really a management decision and an important one at that : for small companies, it's a life-or-death bet and not just a way to piss or rejoice its geeks. It very much depends on how much cash the company has on hands to survive the transition "hibernation". Because when you redevelop a product from scratch, there's nearly no more resources left to continue the day to day maintenance and upgrade on the old installed base. Your customer base whines, shouts, cries, and goes away to the competitors, and your reputation takes a huge blow.
A good company should ALWAYS make a provision (i.e. stashing cash at bank and writing it off from the earnings) to cope with this kind of situation. It must be part of the business model, and not considered as earnings. For once, Microsoft has that perfectly right, just in case : they hold more than 1 year of operating expenses in cash - $25B !
BTW, there's a little nasty perverse side-effect to product transition. If your customers notice a slow-down on fixes and upgrades and you tell them nothing, they get suspicious and pissed. But, if you tell them that something great is coming, it can get even worse 'cause, if they trust you, the darn morons are going wait for the new product ! No more cash rolling in the company account ! That can hurt
There are always alternative... Selecting the best alternative is usually a balancing act. I recently was confronted with just such a problem. I was asked to adapt an existing program to support a new hardware product. The previous program had taken over a year to complete, was poorly written and the author had left the company. I conviced management to that I could re-write the program. Two month later, the new program is nearly complete. It is much smaller, easier to maintain and more versitile. Had I stuck to the original conditions of the project it would have taken much longer to complete and the end product would have had to conform to and support poorly written code. And yet the original program works and is currently used everyday. So there are times when re-writing is appropriate and advantageous. ---When in trouble, when in doubt run in circles scream and shout---
I've just recently had something like this happen. One of the programmers left and his section of code was dropped in my lap. I was the one to continue maintanence.
The code worked but just barely and there were a lot of issues with synchronization and scalability.
The first thing i did was make the code style consistent(braces, variable declerations, header files, It was a mess). Noramally i don't care what style a person uses as long as its consistent.
Next i located the bugs and problem area's. Most of it was just needed error checking and a few synchro locks. I then made some conclusions about the code and put them in terms the upper management could understand. Does it need a complete rewrite, How long is going to take to fix or cludge, if we leave it how will it affect the system and when, How it will delay the project. This project has to do with money which is always a great thing to attach, it scares the bigwigs when you can relate bugs to cash.
Next I started at the begining of the of the section and worked through the process. Rewrote the sections that broke but left his functions and procedures alone as long as they worked.
The point is that if it's about to break, then rewrite what you have to but use whats there even if the function is poorly written, as long as it works.
Anger is an energy. Use it.
Remember:
- Change for its own sake is just change.
- A selfish exercise in brilliance usually looks like a rainbow in the dark without someone to highlight it. (who are you trying to impress? How? Why?)
Strategies:
- Fix the requests you're given within the construct that exists, cleaning up what seems prudent.
- If the code, without restructure, is a threat to the product or you company's position in the industry, document your concerns and wait for the right time to explain them. Spend time on THAT rather than festering on the glop.
- Create a crystal on your own time to buff up your skills and confidence if that's useful.
Focus on your real goals.
If you rewrite the whole thing, in 6 months will you remember what you did? In 6 months, what do you want to remember?
Dave
But if the code was good enough that it (a) had no implementation "features" and (b) had a well-defined interface, then it probably didn't need rewriting in the first place ;)
That's the problem with a lot of "real-world" code - it's grown beyond its original spec and the implementation now contains the *only* definitive statement of what the code does.
I agree with you in theory, though, and I wish I programmed in that world ;)
I didn't pay for my operating system either
Tell them it's a Y2.2K problem.
Mommy. What's a karma whore?
You've mentioned a range of activities within the broad heading of maintenance, from bug-fixing to adding new features. I see these as a continuum (and the nebulous "updating" is somewhere in the middle).
At the more trivial end, bug fixing should almost never involve significant changes. The exception is if the "bug" was an incorrect design in the first place.
At the other end, adding new features depends a lot on what the new feature is, and how (or if) is fits in with the original design. For example, I have worked on a system where the design team explicitly queried parts of the specification, because to implement in a cost-effective manner it would severely limit future (we though) likely changes. Management's response was that the specs were to be implemented as provided, and were extremely unlikely to change. Ever. It was a philosophical thing. Needless to say, less than a year later, we were asked to implement exactly the changes we had anticiplated :-/ I provided estimates to management (1) for adding the features to the existing system, and (2) for rebuilding the system with the existing and new functionality. In this case the second estimate was lower by about 30%, and was approved.
My email is really in an international top level domain. The country code ZZ is spambait.
1) Not all legacy code is nasty; sometimes it is just hard to follow. Be sure that you understand what the code is supposed to do before recommending a rewrite or starting to rewrite.
2) Write unit tests for the old modules. Try to write these unit tests without looking at the legacy code. Legacy code sometimes has bugs; I have seen legacy code that is bug free on occasion. In order to write a good unit test, the programmer needs to understand what the code is supposed to do instead of what it does or does not do.
3) Unit test the old code. Do not change code that passes the unit test.
4) Use the results of unit testing and the estimated effort to implement the new requirements to convince management that a rewrite is necessary.
There is not a clearcut rule for rewriting, sometimes modifying the existing code is the better way to go.
It's called refactoring, actually. Incremental redesign. Check out Refactoring : Improving the Design of Existing Code. Also note that you have to have excellent unit tests. Check out junit
There's also a common scenario in which "fixing" a broken module breaks the code. This can happen because others have coded to depend on the incorrect behavior or it was never determined to be incorrect behavior and now users are familiar with the program working that way. Either way, your fix will be perceived to be the problem.
So, I'd say rewrite/refactor only as an approved task that provides sufficient time to regression test and catch any unforeseen consequences of the change.
There has been some good advice so far in this thread. The big thing to keep in mind is that all software goes through a lifecycle. First you design it, then you write it, then you maintain/enhance it. It's during the maintenance/enhancement phase that things get crufty, but that's OK. Only after things start to become crufty to the point of serious impediment should the major rewrites occur. (Tiny rewrites can occur at any time, but *architectural-level* rewrites should not.) Code maintenance can be compared to other types of maintenance; let's pick house maintenance as an example. Do you pay to have your house re-reroofed every 3 years, or repainted every year? No. To maintain your house in perfect condition at all times is simply too expensive. So it is with code. Having said that, keep in mind the difference between *tiny* rewrites and *architectural-level* rewrites. *Tiny* rewrites are ones that are not expensive, and may be compared to small but frequent house chores such as vacuuming, mowing the lawn, etc. *Architectural-level* rewrites are expensive, and may be compared to putting on a new roof or adding a new room. *Tiny* changes may be made casually, but *architectural-level* changes cannot be done so casually, or done that often. It's all about expense vs. benefit, and keep in mind that most code out there that works is not gorgeous code. That's the pragmatic reality.
Bill - aka taniwha
--
Bill - aka taniwha
--
Leave others their otherness. -- Aratak
I've come across some truly horrific code in my days (I'm self-employed now, I still come across horrific code but it's mine dammit..) in $VBC and well, I had management refusing to allocate time and some people to fixing it up.
My view on it; if you think that code is going to break in new and interesting ways in a few weeks/months - fix it anyway. Do it on your own time if you have to, but keep track of how much time you do spend on it. Fix it on the side, but don't actually implement the fix. yet. Wait for the original code to break, watch management panic and basically walk in and say "i can fix it in (2*the-time-it-really-took) [days|weeks] -if- i get time, resources, and oh.. some days off".
first of all you already have the code waiting so you can now legitimately read slashdot all day (doing research), and you got your name in the good books - not to mention you're on your way to having a reputation as a miracle worker.
okay so some of you might not agree with this approach, but it's worked well for me, and it's a good way to pretty much tell your manager "you suck" without getting your ass kicked. (besides i like watching people squirm and having to explain to -their- bosses why stuff broke in the first place).
There is no sig...
Fred Brooks in _The_Mythical_Man_Month_ (should be required reading for any software engineer) said "Plan to throw one away. You will anyway." However, he was only talking about the initial design/impliment phase.
The real trick is distinguishing between code 'that is bad', and code 'that I think is bad', usually because I'm not used to how it goes about solving the problem. Learning to figure out what someone else's code is doing is the best skill you can aquire early in your working life. You'll be doing it a lot.
Zapman
I believe this means he wrote a really simple multitasking kernel that switched between two processes, compiling it on Minix but not using Minix code. Then he wanted to turn that simple 2-process kernel into a terminal emulator, which raised the question of drivers, and it was on its way to being a real kernel. (If you look at the Linux-activists archive (warning: 600K archive), early Linux seems much cruder than Minix, something which wouldn't have been the case if Linux == Minix being rewritten piece-by-piece.
I have found (at least in my situation in a large corp.) that in order for management to approve anything done, you need to give concrete dollar amount savings for anything you might feel is the "right thing to do".
I know this is hard sometimes to quantify, but in my experience, you can go on for hours with reasonable/logical arguements about why something should be done.And after all of this you get one question, "That's nice...how much $$$ will this save us over what we have now?"It's not so much the savings, but the immediate costs that are taken into account when making the decision whether to pursue something like this.
A way I got around this:
I recently had an idea for my immediate team that would save a few thousand dollars a year in production support. Instead of presenting it to my manager and listening to them saying that we can't afford to spend time on developing it now (usual B.S. from clueless managers), I just went ahead and starting working on my idea in those spare moments during the day, 15 minutes during lunch, etc.I presented it to them saying that this cost them next to nothing (since it was 90% done, and I wrapped the time into other tasks during the day), and it would be ready to implement in a matter of a few days.
You can try to take the credit early on for an idea, or you can work in your spare time to prove it can be done, and that you are willing to make it happen.The latter is what (whether unfortunately, or not) is what the suits will buy into.
Just one person's experience...
At least to your corporate masters it does. Ah yes I can picture the conversation now...
"If you code monkeys knew what the fuck you were doing in the first place you wouldn't be whining at me for more time. Go back and fix the shit you built as all fuck to begin with. Move!"
Whereas if you fix something, even if what you do it a piece of shit drive-by chunk of crap, then you're a fucking hero !
The customer won't notice or care about the difference and if it runs like shit blame it on the hardware or the sysadmins or the crappy db design. Or the H1B that touched it last.
Plus if you patch vs. rebuild you never have to hear from someone else that what you did was a horrible design.
That's what I would do if I were cynical but of course I'm not.
You can understand its function without understanding its implementation. For instance, if you program C, you know pretty well how "printf()" is supposed to work. If you then go open the hood on the printf implementation with intention of adding something to it (say, a new % operator) and discover it to be the biggest pile of rotten bits you've ever seen, then the 50/50 rule applies.
Often, it's much easier to figure out what the interface to a black box is than it is to understand the contents of the box when you open it.
--Joe--
Program Intellivision!
-- Seriously, though - it's very hard to rewrite a program from the ground up; somehow, it's never as good. I'd clean up the code, but not rewrite.
- This statement is wrong, just plain wrong. The axiom in computer science is "Don't fix bad code, rewrite it.
May I ask where you studied computer science? Rest assured, that is not what I've learnt. I didn't think computer science had an answer to this at all, and if it had, I would guess it would be something like "Interesting problem, let's conduct a study by doing both...".
The fact of the matter is, the field of computer science doesn't really care, but the field of software engineering would. (If the algorithm was put into code form, that's generally good enough for computer scientists)
Woz
You have to compare (time to thrash thru bad code) with (time to rewrite + glide thru good code). Suppose it will take two months to rewrite cleanly; in two months, you will not move forward at all, but you will have a very clean base. From then on, progress will be twice as fast as using the old ugly code. Here it appears that 3 months is the breakeven time.
You also have to look at time to market. If your competitors will get to market in two months, then maybe it's better to get there at the same time with ugly code, rather than be a month later, even tho the later code could be enhanced and maintained much better than the competition.
Best you can do is work out the estimates, throw in priorities and market considerations, and take your best shot.
Try various degrees of cleanup. Maybe a moderate cleanup will take 2 weeks and double your efficiency. Maybe a thorough cleanuop will take two months but only quadruple your efficiency. Maybe you do the simple cleanup now, the fancy one six months later.
Compare it to freeway vs city streets. For short trips, the extra overhead of getting to and from the freeway doesn't make up for the longer travel time. Sometimes fast city streets are a good compromise between freeway and slow streets.
--
Infuriate left and right
It is definitely worth retooling code that is awful if
--G
A few things I would like to point out:
1- If you are maintaining code, you should not be refactoring code. There should be 'specific' bugs that you are fixing. Dont do more than this. If you do more than this, the additional changes must be tested, documented, etc. This is not the purpose of maintenance.
2- If the code is that bad, then propose refactoring to management and let them consider and delegate. It is highly unlikely that the developers doing maintenance will be the ones who design the refactored implementation.
Management hates refactoring because they have to justify and fund a project to provide the same functionality which currently exists (although in a much less glorius form)
Development entails not just coding, but testing, integration, documentation, etc, etc. The code part of the project is the smaller of the whole, which is why management may be relunctant, even if you say you can code the changes in a few months.
Yes 4.x was that bad (or haven't you ever used it?) -- After a gazillion point revisions, certain badly formed HTML 3.2 can still crash the thing, for example. Don't forget that they hacked on "Netscape 5" for about a year before coming to the conclusion that their old Mosaic-derived codebase was at the end of it's life.
The "particular function" in Netscape's case was the whole renderer. CSS had to work (not JSS and a bridge as in the case of NS4), DOM had to work (W3C, not layers as in the case of NS4). Even plain ol Netscape inventions such as tables had overhauled to work right. And. once they had committed to rewriting the renderer, it's understandable that they decided to shuck the other things that weren't making people happy (such as the Motif UI under Linux). What's unfortuante is that they didn't start the rewrite back in 1995, like Microsoft did with their Mosaic fork.
--
Business. Numbers. Money. People. Computer World.
Getting sufficent testing resources is the bottleneck in our company and paces our releases.
The upper management doesn't believe in hiring
lots of testers, and people don't like being
full-time testers for long.
Code redesign has to be aligned with testing resources.
Our company has a ratio of 1:4 testers:developers.
MicroSoft advises 1:1. However they have a
hundred as many customers as we do.
Might want to re-engineering your data abstractions (objects) and process flow.
In our yearly release cycles we try to get
in a months worth at the beginning of cycle.
Sometimes deceive the project manager and do
it under the guise of development.
A design cycle might be:
(1) Specification: one month
(2) Development: four months
(3) Testing & bug fixing: four months
(4) cleanup, shipping and vacations: one month
Sneak in refactoring between stages 1 & 2.
I try to rewrite individual sections to make them easy to reuse should the entire project need to be rewritten. So I can fix just the area I'm fixing now but do it in such a way that will work just as easily if I do get to redesign the whole thing. Eventually everything needs a fix or a new feature so you'll get to gradually redesign. This slow process also gives you time to come to your senses if your doing something weird. :)
:)
Also I often write my own versions in my spare work time or in my own time and make my own version. Then you can compare the two versions and if yours is better offer it to your boss to try. If he doesn't want it then keep it for later, he may want it eventually or you can reuse parts. If you wrote it in your spare time then you can make it opensource and/or sell it yourself.
At what price learning? At what cost wisdom? The price is a man's peace of mind, and the cost is his life.
You report back to management what the cost implications of both methods are and let _them_ make a decision.
It's _their_ software, not yours and _they_ have to decide what to do with it.
_____
My Journal
We have a VP of somethingerother here who has a lot of pithy sayings outside his office door, the sort of thing you'd see in a Dilbert strip talking about teamwork, promptness, goals, and I think I'm going to be sick. But he did have one refreshing one which described "intrepreneurs". These are like entrepreneur's, but they're working inside of someone else's company instead of their own. I definitely fall under this category. Sounds as if you may, too.
One of the first things it tells you to do is to come to work every day ready to be fired. I believe in this. If you're fired for differing with your boss on the grounds of a technical topic that you are the expert on and he is not, then you're doing yourself a favor, and it will not reflect negatively on your career.
Another is that there's a difference between saying and doing, and doing should be done underground. Rewrite it without telling your boss. He can't appreciate the importance anyway, so there's no point in making a soap opera out of it.
We can all advise you on the importance of not mucking with code because so many newbies have the unquenchable desire to rewrite, but we're stereotyping you and don't know the actual score. You're the one who has to to deal with that hairball, so you know better than any of us what needs doing. Follow your instinct. Whether you're right or wrong, I gaurantee you that it will be a valuable learning experience.
Project both costs against the short term and the long term. What short and long-term constitute depends a lot on your company. I would say 3 months vs 18 months.
I'm a big fan of keeping parts of a system small and isolated, so they can be completely rewritten when needed without bringing the product down.
-m
--- Hot Shot City is particularly good.
However, this doesn't mean you can't do anything at all. I consider a couple things fairly safe:
eliminate all compiler warnings. Turn on all compiler warning options and either eliminate them or document (in the code) why they're not a problem. I can usually clean up over 2kloc/day and while 80% of the warnings are trivial (e.g., missing prototypes), a good 5-10% are latent bugs. Variables initialized with incompatible data, functions called with the wrong types of parameters, etc. This sounds incredibly stupid, yet I've repeatedly found "fragile" code becomes much more stable once compiler warnings are eliminated.
close memory leaks. Run the software under an instrumented "malloc" package that detects memory leaks -- and ensure that your code always releases all of the memory it allocates. (You might not be able to release code allocated by libraries you use.) There may not seem to be much value in this, but my experience has shown that the effort required to do this always results in improved code. You should also practice "data hygiene" if you do this - clear the data structures before deallocating them, so it's clear if you subsequently attempt to access a freed object.
An alternative approach is to profile the code and verify that there are equal numbers of fopen() and fclose() calls, equal numbers of malloc() and free() calls, etc.
profile the code and find the hot spots. Profile the code and look for the routines that are called most often. Does it make sense, or is this an indication of a particularly inefficient algorithm? Sometimes the code is written one way because of the limitations of legacy hardware, and now it's just a pointless waste of time. (E.g., I've seen routines that opened a file, read each line until the Nth line, the closed the file and incremented the counter! That might have been necessary 20 years ago, but I replaced it with a bit of code that mmap'd the file into memory and then did some pointer magic and shaved 25 _seconds_ off the startup time!)
prune dead code. Run the code through a call-tree routine and comment out all procedures and global variables which are never called. (I find it best to bracket the code with #if 0/#endif and tag each line with /**/ in the first few columns.) N.B., call-tree software can't find functions called indirectly through data structures! Repeat the process until you've found all procedures only called by procedures which are themselves uncalled, etc. Consider moving routines to other files, if it will allow you to make it static. I've found up to 2/3 of legacy code is now dead, and understanding the bit that remainds is *much* easier. Do not delete the "unused code" until a formal rewrite, however!
After all of this is done, the code may still be a undocumented ball of spaghetti, but it should be sufficiently organized for an intelligent decision whether it makes sense to rewrite subsections.
For every complex problem there is an answer that is clear, simple, and wrong. -- H L Mencken
I work for a Java shop where we wrote a component which is kind of our 'flagship' (aka used by lots of customers).
:-)
The initial design was done by a moron, who is just out of Uni and who read too many UML design books, but never seen/written a real program. The code was
- over engineered
- threaded unnecessarily (java threads are easy to program)
- with layers and layers of abstraction.
- and ofcourse BUGGY.
He left and I got to be the poor bastard to support / maintain it. I hated his guts while doing this. But I have become quite an stealth programmer. I have learnt
- a lot of Java thread issues
- how to work around design flaws
- how to do a 'transparent' hack
I have lobbied manager for rewrittnig it. But never got the permission b/c of 'it is too big already / we cant justify the time to rewrite something within 6 months'.
FInally one of our customer who was using this program threatened to pull out of the deal if that component didn't do what it supposed. It took me a week alnighters to get that done. And every day every one from my manager to VP of Eng were on their toes!
After that I had permission to rewrite/design 'parts' of the program. So it is kind of a background process. During my design
- KISS (Keep It Short & Simple)
- avoiding all the pitfalls I have learnt
- unix philosophy (doing one thing & doing it well).
I also have a second programmer assigned, so design/coding decisions are analyzed well aswell.
In my opinion version 1.0 of a program should be simple and v2.0 can be a redesign considering all the user feedbacks.
And the best thing I have learnt is 'you get a design right, after you did that wrong'
LinuxLover
The subject says it all, really. :)
-*- Any technology indistinguishable from magic is insufficiently advanced -*-
"What are we to do when we discover code in the companies products that -really- needs a rewrite and management staunchly refuses to realize this fact?"
Simple. Do what I did. Give up. Spend all your time reading slashdot, working on pet projects, and learning cool new technologies that you might actually be able to use if and when you find a new, better job. I have literally refactored and rewritten this project I've been participating in several times. But I never have the guts to actually show my work, since it would obviously reveal my opinions of the current codebase. In contrast to the recent Ask Slashdot about finding beautiful code, I suggest you learn to live with unconscionable quagmirical morasses of code. Just put it out of your mind, or you will never get any sleep.
It's 10 PM. Do you know if you're un-American?
Just earlier today Reuters reported on incresingly shoddy water and sewer pipes across the country. Basically, some of the major cities are running on piping that's a century old. St. Louis' pipes predate the Civil War. Nobody wants to spend the money to fix them.
This quote from the article relates to code as well as water pipes: "Is the sky falling? No, the sky is not falling today but unless people start taking this more seriously, within 10 to 15 years the cost of addressing these problems is going to be even higher. It's not an issue you can ignore for long."
You cannot apply a technological solution to a sociological problem. (Edwards' Law)
Don't talk to management, ever, for any reason, until you read some Steve McConnell, such as Rapid Application Development: Taming Wild Software Schedules. Also, check out some of the stuff from SEI, such as Investment Analysis of Software Assets for Product Lines. If you're going to commit millions of dollars of your employer's money, you'd better have some research and data to back it up.
read the "mythical man-month". Its a good book written by ex-IBMer about when you should invest more and when you should walk out. First off expect the project to take 1.5x the amount of time. Secondly, putting more people on the job is not always the best solution. This book explains on how that can actually put you behind because the new addons need time to catch up with the rest. I thought it was a good book, I give it 2 thumbs up and a phat toe.
what is the definition of a coward? a man who thinks twice about fighting a lion. what is the definition of a braveman?
Make sure you understand the system first!
You mentioned that you are Junior developer.
Many re-design efforts start from not being
able to understand how system works.
True, but on one serious condition: The rewrite is done by the same person(s) as the original. When rewriting someone else's code, you are will have to map the other guys mental model from his source, form your own map of how things should be, and transform that into code. Much less effective than rewriting your own code, where you can reuse the mental map you built the first time, especially the parts you realized when it was too late to change, and had to kludge your code to work anyway.
In Murphy We Turst
At the very least be aware that "here there be dragons". More often than not when I run across some piece of code that makes me exclaim "What brain-damage is this?!?" I later discover that some other bletcherous mess is depending on that particular flavor of brain-damage.
If a piece of code has a tight enough interface specification that you can actually get away with the 'school-taught software-engineering, it's a black box we change the insides at will' mentality -- then chances are that code isn't crying out for a rewrite in the first place.
Shut up, be happy. The conveniences you demanded are now mandatory. -- Jello Biafra
So my advise is to only "stick your neck out" and "go the extra mile" if you really care about the code or project. If it feels like someone else "owns" the project and you're not in control of its direction, advocating and persusing a re-write is probably unwise.
PJRC: Electronic Projects, 8051 Microcontroller Tools
This argument really could go either way, depending on the size of the system in question. If it's small enough that you actually can understand almost all of it, then a rewrite will probably be superior to the first implementation. However, you're definitely right in asserting that a rewrite of something you don't really understand will turn out to be just as crummy as the original, but that's because you didn't really learn the subtleties of the problem space from the original. Rewriting something small can be a winning situation, but bigger systems will almost always be a nightmare. I think Netscape 6 would be a good example. Sure, it's finally getting good, what, 2 years after the rewrite began?
Just remember, when you're thinking about whether or not to do a rewrite: don't do what Netscape did ;)
If you've only maintained the system for a "few hours", I doubt you really understand the system well enough to pull off a redesign and rewrite. Not to mention that it'll be a hard sell to management.
I've seen new hire after new hire come into a company, look around at the steaming heap of code, and within a week want to rewrite it all. The best fun (as their underpaid "peer") is being supportive and getting them to go ahead and try it. It's fun watching wiseasses hang themselves.
On the other hand, almost every time I've done a rewrite like this, I kicked myself repeatedly for not doing it sooner. The only times I didn't? When I was that new wiseass that didn't really understand the system. I was slowly sucked into a downward spiral of rewriting more and more pieces until I scrapped it and hauled out the duct tape and chewing gum.
If you really want to pull off a rewrite, just go ahead and sneak it into your schedule. Don't bother trying to get management to understand the issues. They don't see things like you do. They're almost a different species. They figure once something is written and works, it's finished.
Actually, the adage "If it ain't broke, fix it 'til it is" works better here. When fixing it to make it do what you want breaks it, you need to redesign it. If you can fix it without breaking it, keep it.
It seems to me that your management wants you to keep fixing the system until it breaks, at which point you're allowed to replace it. If you honestly cannot fix it to work, rewrite it.
Some things to remember when rewriting, though:
You are in a maze of twisty little relative jumps, all alike.
I have been programming for a while now. I have seen a lot of ugly code. One thing about that ugly code sticks out at me: it was all ugly. It is remarkably odd. Funny how all *that* code was ugly but mine wasn't.
At this point in my career, I believe quite strongly that the only time you should rewrite is if you are changing to another language. Even then translation is often a good idea.
If it is in the same language, make it better. Is a method too long? Find some lines of code that represent a task and move them into another function. Would this one really big procedure work better as three classes? Peel off a class at a time. Refactor the heck out of it until you are happy. Test often. Code a little, test a little. Before you know it, that Pinto will start to look like a Porsche. At the same time, you'll keep all that knowledge that someone worked so hard to put into that code.
Refactoring isn't a new idea. Martin Fowler wrote a book about it and there are some sites on the internet if you look hard enough. The important thing about the book is that it is liberating. It was the first thing that ever suggested to me that I might try fixing bad code.
Rearchitecting might sound like the best answer, but be brave. Software engineering is often about maturity. Someone who always says "if the company isn't right then find another company" might be missing out on something. If you can help your company success, you just might find yourself succeeding.
They do this with heritage buildings as well.
;-)
oh, you meen like Win9X?
I am become Troll, destroyer of threads
It's important to remember that when you throw out old code, you can be throwing out hours of productivity and learned knowledge in the from of incorporated bugfixes.
Was is *really* important to throw out the ftp code in netscape that understood all 60 types of servers to connect to? surely there was something worth saving.
Yes, spaghetti code is nasty, but if developers spent more time reading the code they have on hand, re-use would be more prevalent.
An opinion is simply that, and I'm entitled to mine.
If you feel baited to flame me for a perspective that differs from your own, well then, that's more about you than me.
A host is a host from coast to coast, but no one uses a host that's close
Management doesn't usually listen to a junior engineer who says the system needs to be redesigned. Chances are they have a senior engineer who is already saying something and trying to echo it up to an Architect or CTO who has some sway.
That isn't a nice thing, but it is the truth. Lower management wants to avoid the ire of higher management. Generally they are going to say something to the effect of "Just get this one item working" because just that one piece will take a fraction of the time it would take to redesign the system. Does it matter that they are going to lose the time taken to redesign and then some over the course of months? No, it doesn't.
Ultimately there is someone who wants the software and they want it now, and they are not going to tolerate having to wait two months while the infrastructure is refactored. You can show upper management all the supporting evidence you want, but if doing this is going to seriously impact their short term cash flow (or any number of analogous tangible items) then they are going to want to hear how a bandaid fix can be implemented.
Yes it sucks, yes I live it. One skill that moves you up that Junior to Senior ladder is your skill at finding interesting bandages to treat a sick project.
Education is a better safeguard of liberty than a standing army.
Edward Everett (1794 - 1865)
is when you get to the point you're at. If you see a problem, or realize that a redesign will make it better than just a little here and a little there, then you re-write it. It's your decision and not managements. On the other hand, they fund you so you'll have to convince them.
My karma's bigger than yours!
SIG: HUP
Worked with a really bright guy once, had an amusing story about his brother, another really bright guy, just a few circuits missing. Managed to convince management - through a very good looking cost benefit ananlysis study - that removing all documentation from the programs would save on storage and thus money. They bought it; he wrote the code that wiped out all comments; and they have had virtually zero new employees last a year before quitting in disgust (this for the last decade). The programs there are old, huge, and insanely modified/complex.
Yep, it's a gov't installation. Remember - most gov't employees are not paid for how well they do their job, they're paid for how many people they have (i.e. NEED!) working under them. This sorta qualifies as a negative incentive towards efficiency.
There is another reason - system performance. I'm not talking about stability - that should be part of any working program. I'm talking about things like actual run-time, memory usage, storage usage, and the like. I once worked at a company that had a very narrow batch window (8:00 p.m. California to 5:00 a.m. London), and was starting to get seriously concerned about programs which, due to the huge increases in number of records processed, was starting to exceed that window. Re-writes were ordered, and hours shaved off a number of the largest programs. Another I worked at had a program that built a DB (RedBrick) from nine different user-supplied files. All initially on tape. With 5 or six of them less than a thousand records (the rest were around the 100 million count). The original program could be using up to nine different tape drives, and ran for eight hours. Loading the 5 or so files into memory dropped run time to under an hour.
You _can_ generally sell management on a rewrite if you can cost justify it to them. Most places are scarce on personnel resources, which kinda conflicts, but telling the management that a week of your time will save x odd hundred thou a year tends to make them perk up and listen.
"Ancillary does not mean you get to rule the world." --U.S. Circuit Judge Harry Edwards, speaking to the FCC's lawyer
It may be that you just don't understand it to the core yet. The one thing that I hate is taking over something that somebody else wrote. My way of definig variables, writing comments or use of a case statement might be different from another persons. More often than not just adding comments to what is already there helps fix problems like those mentioned. So before you go back to the drawing board, learn what has already been done. It may be brilliant.
I spent a few years doing PL/I in a mainframe application that bills about $6,000,000,000/year, so please believe me when I say I know how you feel.
Long story short: been there, done that, should have bought the T-shirt ... and very nearly got fired. I learned the hard way that they don't pay you to make it look pretty or even to make it run more efficiently. THEY PAY YOU TO MAKE THE DATE.
Trust me: this is the kind of medicine that it's best to take in very small doses: I know how frustrating it can be to have to wade through a mess that someone else left behind, but try to stay detached and avoid the temptation to reinvent the wheel. As other have pointed out, you can improve small sections of the code, one release at a time, and you'll have 80 percent of the possible improvement done in 20 percent of the time a rewrite would take.
Here's some free advice: the next time the urge strikes, just take a walk around the floor, and remember that everyone else has felt the same way at one time or another. Then, get back to work and make your date, because that's what pros do, and it's all anyone will ever remember.
Then, go home on time, help your kids with their homework, and rest assured that you're doing a lot more to make the future better than you could ever do trying to re-re-rewrite some piece of spaghetti. As for the rest: that's what optimizing compilers are for, you know?
Bellhead
...who started out with Minix and gradually replaced code until none of the original was left. You're right, though, the result does resemble UNIX an awful lot.
Brackets contain world's first nanosig, highly magnified:[.]
There may never have been any minix code in any version of linux distributed as such, but by his own words, when Linus began writing Linux he started with the Minix codebase and worked by replacing it piece by piece. By the time he got around to showing it to other Minix users there was no Minix code left, but that's how he started. He actually used this as an example of how you can approach a seemingly huge project when there is something inadequate but similar to use as a starting platform.
Stop showing your ignorance.
Brackets contain world's first nanosig, highly magnified:[.]
If management doesn't seem interested by conversation, make a proposal/report. Nearly everyone in high school, anywhere, had to write one sometime. It would take a couple hours to make a concise explanation of the reasons and a written copy is always taken more seriously than a mention in the breakroom or a random e-mail. Keeping good records, taking initiative, acting proactively, and carrying yourself professionally gets you noticed and promoted.
Most importantly... it covers your ass when people ask later why you didn't fix the problem months ago.
Never been in a company where people would leave rather than work on the existing codebase? At times like that, management might reconsider. And if it's going to take such a dire emergency before they do consider rewriting the codebase, they're lousy managers.
I didn't pay for my operating system either
Go ahead and refactor; but for god's sake, don't dump & rewrite! Look at this for further explanation
It's amazing how local transformations can introduce quality to systems with no conceptual integrity.
But to really be effective, you have to be aware of where you started and where you are headed. The big picture is a lot of little pictures, hopefully connected by a coherent architecture.
One of the best ways to move toward coherent architectures is to start thinking in terms of design by contract. Think of preconditions, postconditions, and invariants as part of the public interface, just like routines' signatures. If your language doesn't support them directly, you can probably get free 3rd party tools that will help. Even if you can't, put them in as comments. Program code is documentation of the write once, read many times, variety.
Learn and get comfortable with as many variants of as many patterns as you can. When you use them, mention them in your comments.
This anonymous coward is Tom Morrisette
Over the course of the next year or two as I maintained this utility I began by rewriting individual routines and then moved to modifying small sections of code in the end there were probably only a handful of the routines in the codebase that hadn't been completely rewritten.
If you cannot do that, then perhaps you are the one that needs the adjustment.
--
Sorry, but I have to take issue with this:
;) developers should always be weary of what Brooks calls the "Second System Effect", whereby needless features and are added. More info on that here.
Seriously, though - it's very hard to rewrite a program from the ground up; somehow, it's never as good. I'd clean up the code, but not rewrite.
This statement is wrong, just plain wrong. The axiom in computer science is "Don't fix bad code, rewrite it. Yes, I realize that's the CS take on things, and that it doesn't always jive with business needs. But I digress.
Second systems are typically easier to write because the hard part is already done: transforming the mental model of the system into real, working code. Plus, you get the benefit of lifting out portions of the old code that are worth saving. Also, second systems are easier to write because the entire idea has been realized via code once, and that means that you should see patterns and behavior that were not obvious when the initial coding began.
OTOH (because I like to argue, even with myself
A lot of programmers start out re-writing with good intentions but usually wind up with something just as bad as what was originally there.
In order to avoid this problem, the programmer must analyze the code and have an intimate knowledge of what the code does and what it is SUPPOSED to do. After looking at these two things, the programmer must analyze what the impact is going to be for both fixing the code and replacing the code.
Once you have this information you can then assess the risks involved with both approaches. The programmer should also be aware of what the long term goals of development are. Its possible that you could be rewriting a section of code that will no longer be used in the next release. This would be a waste of your time as well as the companies.
One of the largest risks of rewriting a section of code is that you may change the intent of that code or introduce new side effects that you hadn't thought of. If the code has been around for a long time, chances are, that code for the most part works and should only be fixed. If the code has never worked, then it could be a good candidate for re-write.
When we fix bugs where I work, we are required to fill out a Design Change Request (DCR) form for anything that requires significant modification to the structure of the code. If it's a simple fix, then we fix it. The DCR is then submitted to a manager and they review it and approve it. In the DCR you state what problem you are trying to fix, what files it affects, what you plan to do, what side effects it might have, and any other alternative solutions that might be feasible as well.
What a DCR does for the programmer is it gets them to look at the problem in detail, and to understand what impact their solution may have. It also gets the programmer to look at alternative ways of solving the problem.
I can't count the number of times I've switched solutions because I thought of a better approach. Had I just started in and started fixing and or replacing code, I would have been wasting time and energy on something that might not have worked in the long run.
The last thing I want to say, is that Documentation and Planning for Change are critical to an application that is going to be easy to maintain down the road. Documentation (i.e. Good Comments) are not for you, but for that poor sap that follows you. Help them out!
Visit the Arcade Restoration Workshop @ http://www.arcaderestoration.com
When it is really time to rewrite a product, management will be willing. This is because it will be truly more expensive or impossible to get the functionality requested by management out of the old code base.
Until then, they are correct in their judgement that it doesn't need rewriting. Elegance doesnt pay your salery.
When you need to improve a section, learn what the code does, and if you must, rewrite the section. Keep the general system in place. Designing a system is more fun than debugging an old one, but your new system will be just as painful as the old one is.
In 5-7 years, the programming style you use will look ugly and primitive compared to whatever the latest buzzword in computer science is. If you rewrite whenever something "looks ugly" then you will be perpetually redesigning, and that isn't an efficient use of corporate resources.
Tonight I rewrote some code that traversed a tree depth-first in reverse. The old code wasn't working right, and it was too ugly to see by examination what was wrong. Rather than debug it, I wrote a class that represented position in the tree, with "next" and "prev" methods. The tree-traversal function then became much simpler.
If they ask you for maintenance, give them the gory numbers for effort-required, especially after you spent some time understanding it (show them the bill for that time too). At some point they'll go, "You know, maybe it's time we cleaned that code up."
A friend of mine once rewrote the core of the application he was supporting by replacing bits and pieces here and there until he installed the new architecture from the inside-out. They do this with heritage buildings as well.
The bitter lessons of a veteran coder: http://bitterprogrammer.blogspot.com
One, go in there, convince upper management, and rewrite the whole thing.
Two, add another layer of obfuscated code on top so you can get hired back as a consultant when the whole thing goes belly up and no-one can understand it.
Three, perform an 'accidental' disk wipe and force a code rewrite.
Seriously, though - it's very hard to rewrite a program from the ground up; somehow, it's never as good. I'd clean up the code, but not rewrite.
You might pay particular attention to his habit of writing unit tests before he does anything.
1. Tell my manager about the nasty convoluted code.
2. Told her I could rewrite it, or try to hack what's there.
3. I Told here that in the long run it WOULD need to be rewritten, but then again it was a short term project, and I could probably make what was there work.
She decided that since we we're at feature complete, (about 2 months from shipping) It would be better for me to just hack at it. So I did, it worked out ok, I learned more about what the previous guy was doing and managed to work with it.
Sometimes there's code that no one likes, even the author. I think a lot of people have natural attraction toward rewriting something then learn and deal with what's out there. Personally I didn't care what my managers decision was, It wasn't my call, my job is to write the code for the tasks she gives me. Not to take on big projects that will risk the ship date.
-Jon
Streamripper
this is my sig.
The only point to going back to re-doing something is if the users are ready for a significantly enhanced product. If the thing they have is working well enough for them, you're going to get zero support for an effort to clean up the code, even if it will reduce maintenance work in the long run. Clean bits here and there while you fix other bugs, but a complete rewrite is only warranted if the software system is really not meeting current requirements.
Energy: time to change the picture.
There is NO WAY you should do this.
If you are doing bugfixes, fix the bug.
If you are planning a rewrite, or find yourself rewriting major portions of the code, you are making a terrible mistake.
One, if you have to rewrite major portions, it was improperly designed in the beginning. This means a group of people, familiar with the task at hand, did not sit down and do a proper design. Note that you are not doing it either!
I don't know many times I've seen people start debugging and rewrite the code, and the next person sees it, says its all junk, and rewrites the code, ad infinitum.
Don't do it unless your serious, and if you are serious you need to be much more formal about it after the bug fixing is done.
BTW, has anyone else noticed what appears to be a pengiun sticker on the back of Johnny Depp's guitar in the "Chocolat" movie?
Treatment, not tyranny. End the drug war and free our American POWs.
See my user info for links.
The best way to keep software clean over time is to redesign parts when you add functionality, otherwise things will only get worse over time. Tell management that it is called refactoring, if you think that helps. The wonderful fact about redesigning when needed is that you can do as little or as much of it as time and budget allows. And whenever you feel it is necessary.
The important thing is to stay in contact with management. Typically, you will be fixing a bug, or adding some functionality. In order to do that, you will often need to understand a component really good. At that point, you can tell the management that the chosen component, which you now understand perfectly, is a big mess. Tell them that since you have worked with it for over almost a month now, you know it's in and out's perfectly, and that you have some ideas for a better design. Tell them that you don't want to rewrite it all, because that would be to costly, but that there are some parts especially crufty, that it would be better to rewrite, and you would like to do just that. You can even tell them that it would probably be cheaper to to that then to just add your cruft to the other cruft, as it is probably true.
But don't lie to the management! Be honest, and tell them exactly why something needs a rewrite. There is very rarely a need for a total rewrite! Most code that exists are there for a reason! Sure, it can be cut&paste code (modularize), it can be deeply nested long blocks of hard-to-understand code (modularize), and it can be ugly non-portable code (clean up). All these are good reasons for a minor redesign.
But whatever you do, don't redo it all! Unless you wrote the program yourself, chances are that you will not do a better job than the previous guy! It might be hard to accept for someone who used to be a hot-shot programmer at the university, but there do exist other good programmers than yourself!
If management resists a total rewrite, then they are acting sensibly. While you don't understand all of the code, chances are that most of it is there for a reason. Even rewriting a single component from scratch is more than likely going over your head. The company is more interested in keeping software working than in having to do new regression tests three times over because your new module didn't work exactly up to specs.
And trust me, if you think coding is expensive, I tell you what, testing ill-designed components (which they have to be, given that you only redesigned a small part) is very expensive. And if the software is mission-critical (which it often is), or it is sold to actual customers, it will get even costier.
So, just grab a beer, start coding, and be thankful that you can at least make a small bit of the cruftiness disappear. If you want something else, you'd better wait untill you've proven yourself for the company, or start for yourself.