21

Possible Duplicate:
Prototyping vs. Clean Code at the early stages

I'm right in front of a difficult decision.

I have a problem in my codebase (it's in C++), which I could solve in two ways:

  • A) Add one line of code
  • B) Rewrite ~7500 lines of code, adding roughly 1000 for an additional messaging switchboard class

Now, at that point any sane person would probably tell me to chose A, but:

Solution A would be hacky. In my case what I mean by this is that it would:

  • Involve adding coupling between two classes that normally shouldn't know of each other, and shouldn't interact except over an external manager class

  • Lower flexibility

  • Cause future classes in the same league to have the same problem, thus creating more hackyness if the solution isn't changed

I'm sorry for the lack of concrete information, but explaining my situation probably would take 1,5 A4 pages of paper - and the decision is really a general one.

So, what do you think:

  • Should I choose solution A or B?
  • How hacky are things allowed to get in a project where clean and logical code plays a great role?
  • Are there any general guidelines on avoiding the phenomenom of "hacky code"?
8
  • 5
    When's the deadline? How long do you expect the project to live on? Commented Aug 9, 2011 at 21:49
  • 1
    Difficult to say without context, but in general I would say "You can take a shortcut now, but you'll pay for it later".
    – Bart
    Commented Aug 9, 2011 at 21:51
  • 7
    Obligatory: xkcd.com/292
    – Chris Lutz
    Commented Aug 9, 2011 at 21:54
  • 17
    I refuse to believe these are the only two extremes available. A little thought might turn up a third option that is better. Commented Aug 9, 2011 at 21:54
  • 4
    Only you can judge it, but factor into the decision correctness. Even though A is hackier, you may well be extremely confident of its correctness? With option B, all that re-writing opens up serious scope for regression. Do you have time to test properly if you take that route? Commented Aug 9, 2011 at 21:57

9 Answers 9

26

Wait until you have about three hacks because of the same problem and then refactor.

If you are just avoiding a single hack, then I suspect you do not actually have enough information to determine the best solution to the problem. I suspect you'll be able to find a better solution by delaying its implementation until more problems of the current solution manifest themselves.

Basically, delaying will give your more time to collect information and thus will produce better code when you do it. However, delaying will also tend to make the situation worse. So, you should keep an eye on the situation and when its clear that is getting worse then you should attempt to resolve it.

3
  • 4
    +1 for the golden rule of refactoring/reuse. The first time, just do it. The second time you write the same code, cringe, but do it anyway. The third time you do it, refactor it into a separate function. Commented Aug 10, 2011 at 7:07
  • 3
    That works as long as you're the sole contributor to a code base. What if you don't trust the 3rd (random) person to do the right thing? Is it not better to lay the right foundation from the beginning so that other less conscientious developers are not tempted down the line?
    – Kevin
    Commented Aug 10, 2011 at 15:13
  • 2
    @Kevin, well... yes having the right foundation from the beginning is best. But the situation here is where you've discovered midway into the project that the right foundation has not been laid. Do you rip out the foundation right away to replace it? It clear that you didn't make the correct design decision originally. What makes you think you are going to make the correct decisions now? That's why I think you should wait until you get a better picture of the situation, not the first moment that a hack is necessary. Commented Dec 25, 2011 at 7:04
11

First, talk to a manager, and (I would) argue for the "do it right". However, your employer probably doesn't want to pay you to change all that code when there's a shortcut. In that situation, I would put the hack in a well-named function or macro, and document it very very clearly.

4

First of all being pragmatic at one point or the other is a good thing. There seems to be no immediate danger in going for A other than that it's not the 'right way to do it'. As long as you clearly document your code smell it can be acceptable.

What you need to do is weigh the pro's and con's both shortterm and longterm

  • Is the time you would spent in doing B value for money for your client?
  • Do you have the time to do it or could you create more value by spending it on something else
  • How likely are you going to suffer from the 'lower flexibility' and how much extra effort will that lead to.
  • Can you postpone refactoring it until you actually run into the 'lower flexibility' issue

As for the general guidelines. You have run into the typical trap of detecting a design flaw way too late where it now has become so expensive to correct that you almost can't do it anymore. It's not always possible to prevent that but things like code reviews and even pair programming do reduce the chances of this happening. Also have a look at this wiki page about code refactoring and whatever you do ... "refactor early, refactor often"

2

Unfortunately this kind of code rot happens in project which are in a hurry..

If you have the time and on the long term it gives more benefit then definitely do the refactoring.

2

If you fully owned the company and had to pay someone else for the solution, A or B, which would you choose?

I usually go with avoiding hacky, but a 1000/1 ratio of effort is an extreme case. If you are sure the hack is the first step down a slippery slope then avoid the hack if you have time (and if not make time soon), but if not I would say to do the hack and maybe it will work out fine - the future may surprise you.

If you do the hack then change your mind you are only one line of code worse off than before (as I understand it). If you write 7500 lines of code and it turns out that all they do is replace 1, you can't get the time back.

Also, 1,000 new lines of code may well add more complexity than one line of hacky code.

If the numbers change over time and make a better case for writing the messaging switchboard my advice would change, of course.

2

Don't do it if at all possible

The problem with adding 1 hack is that it opens the doors to put in another, and another and eventually you'll end up with a brittle and fragile framework which is pretty much the antithesis of what you're trying to build. - Overly optimistic

Taking on technical debt

The problem with what I just said above is that it's pie in the sky, we don't always have the luxury of the perfect solution, or time. However if you can stress to your boss that they will be taking on significant technical debt with the "hack". They can set aside time later on to pay that technical debt back before it becomes too much of a problem and it stunts future development.

1
  • 1
    +1 for living in the same 'fantasy land' I do. I wish reality would catch up to us... Commented Aug 9, 2011 at 23:27
1

One hack is acceptable. Five-ish hacks of the same kind indicate a pattern that probably should be addressed on a higher level. You also seem to have discounted the hidden cost of rewriting a large amount of code and all the bugs you will introduce.

And: is it REALLY a hack? From your description, the classes cannot work on their own anyway [since you need a "message switchboard"], so why do you think that coupling them in a short and straightforward way is bad?

0

It's not that complex IMO. You are weighing up the time saved by doing the hack vs the risk that A. you may need to do it anyway in the end, thus the hacking was a waste and B. The hack is more likely to cause maintenance issues down the track.

There is no rule that you must always refactor when required.

0

If you've got the time and the test coverage, do the rewrite. Sure, the alternative may be one line for you, but what if you win the lottery and quit your job tomorrow? Will your replacement know about that one critical line hidden among the 7500 others? And how long will it take you to rework 7500 lines anyway? Two, three days? It sounds like you know what you're doing, it's really nothing more than a (larger than usual) refactoring task.

Of course, if you're up against a deadline, then plan A is the way to go. Just make sure you document both the hack and "the right way" that you would have done if you'd had the time. Then hopefully you'll get the chance to circle back the DTRT after the release.