19

In my team, people have tendency to develop a POC (which is very close to actual deliverable in terms of features) which takes good amount of time to be created. And then spend a significant time to refactor the POC so that it matches the design principles using all required design patterns, sometimes naming etc...

One advantage everyone in team says is you have the confidence to meet deadlines one so called POC is ready, then you can spend time on design.

Just curious about, is it really good to refactor code after developing it in quick mode or we should spend time initially to work on architecture and design of the code?

EDIT: After reading the answers I realized that, as most of guys said, what I am talking of is more than POC and as rightly put by Carl is an "evolutionary prototype." This is definitely not a throwaway code. Intention of the output is always to go to production.

Maheep
  • 261

12 Answers12

13

Someone, I believe it was Steve McConnell, probably in the first edition of Code Complete, made a very important distinction. There are two kinds of prototypes, throwaway and evolutionary, and both are valuable. And we make a grave mistake when we confuse the two.

A throwaway prototype should be very quick to write; it's what I think of when I hear "proof of concept" (I prefer the phrase "test of concept" because proof seems to imply an expected outcome, and if you know the outcome, why bother?) Because it's quick to write, you can throw it away without misgivings. And you should, because its code quality won't be up to your usual standards. You learn what you need to from the throwaway prototype, and then you throw it away and apply what you have learned to your production code (remember, what you may have learned is, "this doesn't work;" that's a very good lesson).

An evolutionary prototype, to the contrary, is designed to evolve into your production code. This is slower, because it must be written to satisfy your coding standards: exceptional cases must be handled, tests must be in place, proper commenting and naming, etc. This can be a good way to go, but it's obviously a bigger investment than the throwaway prototype.

The critical mistake many organizations and developers make - a mistake it sounds like your organization is making - is to start with a throwaway prototype, and fail to throw it away. Because now you've got crap code (on purpose), and you're trying to put it into production. Don't do that. Throw away the throwaway; that's what it was for.

9

If you're spending so much time refactoring your (nearly feature-complete) POC to meet coding standards, it's time to consider whether those coding standards are actually helping. Are those naming standards actually helping you write better-quality code faster, or are they just adding needless busywork?

Of course, you say "very close to actual deliverable in terms of features" - the next question is, of course, how much time you spend squashing bugs. If the POC is actually mostly bug-free and nearly feature-complete, and with just a bit more work (if you skipped all the coding standards crap) it would meet all the client's requirements, then it's not a POC so much as an alpha or beta build.

In any case, whether this approach will be successful can depend on your team. If it's working for you - great! But if you're spending a lot of time on "refactoring" that doesn't actually help, it may be worth reconsidering whether that refactoring is actually useful.

This isn't to say that refactoring is necessarily bad. It could be that your "quick mode" code is an unmaintainable mess and the refactoring really is needed, in which case perhaps this "quick mode" isn't such a good idea. This, again, depends on whether your team is good at making more-or-less maintainable code the first time around. But, from your description, it could just as easily be a big waste of time.

bdonlan
  • 766
6

It is nice to get time to refactor the POC.

In many environments, if the POC is good enough, it gets deployed anyway, you don't get time to clean it up, and the problems don't emerge until you end up having to do some maintenance, or add a few features, in a year or two's time.

If this approach works in your environment, then I wouldn't suggest you stop using it. But if you try to port it to a different environment, be careful.

To me, a "Proof Of Concept" would be just enough code to prove to myself that I could make something work. No bells, no whistles, no error handling, no features that I was comfortable with unless they were absolutely critical to proving whatever the core thing was. The worse it looked, the better, on the grounds that it would be least likely to get pushed into production.

Then I'd start from scratch with my normal development methodology, using the POC (or spike) as a template when the appropriate time came. Perhaps whatever concept I'd just proven would be the first feature I built in this second version, but more likely I'd need to do some other stuff first to prepare the ground.

Bill Michell
  • 1,990
1

If I was allowed to I would personally prefer to work in the fashion you have descibed: Get something working first and then designe a nice class or whatever as per design prinicples. After all what good is a pretty design if you cant get it to work.

In fact Bruce Eckel also recommends "buid one to throw" as an effective programming technique. This is very useful when you are doing something that is technically complicated or very unfammiliar( a new library perhaps). Doing a POc gives you a very good idea about how your design should be.

If you already have a good grasp on your project's requirements and your design works fine say 70-80% of the time without refactoring then I think you are better off without a PoC. But if you spend more than 40% of your time refactoring your design to get it to work you are better off doing a PoC first .

As you have mentioned unit tests let me add : if youa are required to do TDD you need to get as much of a "right design" before you begin coding. If you do a POC first you can save yourself the trouble by not doing TDD along with the POC. First do a POC , then design your classes, next write the test cases. This way you dont have to write two sets of test cases.

DPD
  • 3,527
1

My approach - either write it "almost right" the first time or rewrite from scratch using POC as a project/draft, not the final piece. Sometimes I extract large chunks of code from the POC porting them into the final product - the ones I deem them especially successful and well written. But bulk of the code is rewritten from scratch.

Of course the POC will sometimes work as a stub for the final thing for a few days (or months... depending how critical the piece is as the deadline on more important stuff is looming), before it is replaced by the real thing. But that's not a good practice.

SF.
  • 5,236
1

you have the confidence to meet deadlines one so called POC is ready, then you can spend time on design.

The correct question to ask yourself as a company is not if you have the confidence to meet deadlines when the POC is ready, but if you have the discipline to refactor and write unit tests before going to production.

Especially in an environment that is heavily weighted towards sales concerns, the temptation is just too great for the company to hand off the prototype as the product with minor modifications, typically without regard to the maintainability and the technical debt that will accrue later. Four months later when the customer comes back and says, "It turns out that we do need the program to track ad-hoc visits to facilities. How long would that take?" then that situation could force the need for a rewrite of the prototype anyway. A project that should have taken a few months is now almost an 8 month project and the customer is angry about time and cost over what seems to them is a fairly simple feature.

It sounds as if you work for a good company that understands the dangers of NOT refactoring your POC before using it as the product.

maple_shaft
  • 26,570
1

I'm going to say no. Speaking from experience, 9/10 times if you write a program quick and deploy it, you won't be able to make the time to refactor it as management/client sees they got results fast so you will be inundated with more work that is expected to be done just as quick. You'll end up with an awful program that keeps getting larger and larger.

Best to take the extra time and do things right. It's slower at the start but faster down the road. Short-term vs. long-term thinking - long-term should always win unless you aren't serious about what it is you're doing.

Wayne Molina
  • 15,712
1

Programmers are authors, and even the best authors don't get it right on the first draft. There's a very simple reason for this: programmers who have worked on a project for a month are much more knowledgeable on the subject than programmers who haven't worked on it at all.

However, scheduling in a refactoring phase isn't the answer. You need to be doing continuous refactoring as you go. When you find a cleaner alternative to an architecture that turned out to be awkward and bug-prone, refactor it right then. You might think you're saving time by putting it off, but what you're really doing is condemning the programmers to work on an awkward and bug-prone architecture until the POC is complete. That greatly increases the risk that it won't work, makes the job more difficult, and therefore it takes longer, even in the relatively short term.

Karl Bielefeldt
  • 148,830
0

I personally prefer getting the main deliverable right from scratch. I always have one or two throwaway projects alongside to quickly test or distillate some ideas, but even working in this way, refactoring is inevitable.

Usually I wait with writing unit tests until I'm perfectly satisfied with a class. I've tried writing the tests before the implementation but my development time quadrupled keeping all the mockups up to date due to my urge to have everything compilable at all times (maybe I should just learn to relax, but I'm kind of rusty this way).

On the other hand, probably I'm too much of a perfectionist. Commercially the quick POC and patch might be a more economical choice.

0

I think this is ok depending on your situation. Writing a POC to get from A to B as quickly as possible, and then fleshing it out, and ironing out the creases is certainly a strategy that can worked and has worked for me in the past. The refactoring is not an afterthought though, you must refactor aggressively, do lots of it, and allocate significant project time to it.

I think your decision depends on the quality of your POC. If it's high quality (it may be 'rustic', but that doesn't stop it being high quality) you shouldn't start again from scratch at all. It wastes time - I've seen this - and if you get the new design wrong it's frustrating and you'll be saying "if only we'd stuck with..." then people will have to work hard to refactor anyway. If it's low quality, then you are more likely to have got the approach wrong in some way and you'll hit an show-stopper at some point in the future. I've discovered the opinion of the quality of your codebase may vary amongst your team members. You need to work out who is right. You're looking for good high-level design, that will accommodate future concerns, and you can ignore most of the smaller scale badly written/non-idiomatic/loose stuff to an extent.

Whatever design you have, try to look ahead with it, identify the biggest required changes and make them now. Once you're further down the development road it'll be harder to change the overall structure.

Benedict
  • 1,097
0

The scenario you describe doesn't have the ring of truth to me. My guess would be that your proof-of-concept is quick to do because it is not robust, and is probably buggy. This is what I like to call "smoke and mirrors" because unfinished software can easily look finished to clients until they have to use it to do their job.

If I'm right, the cleanup that comes later can't be called "refactoring" so much as accounting for all the edge cases, eliminating bugs, and responding to feedback (which inevitably requires 80% of the time anyway). I suppose you might mix this with cleanup and therefore conclude that you are "just refactoring".

It's possible I'm wrong. The kind of thing you're describing just doesn't fit my personal experience. A proof-of-concept is generally most valuable in reducing risk, and it will prove the feasibility of just those portions of a project that seem most likely to fail unless they are well thought out in advance.

0

It's amazing how many prototypes end up as being the final product. I would say follow your coding guidelines to create the prototype and once finished it shouldn't need a great deal of refactoring or else your guidelines need updating. Do it as near as right as you can the first time.