18

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.

7
  • 4
    Do you have tests that make sure you don't break too much (anything?) during the refactoring process? Also, who does "require" design patterns? Shouldn't you use them to solve the problem and not introduce them afterwards? Nov 4, 2011 at 8:32
  • Yes we do have unit cases, and my bad luck is, even they need refactoring as classes they test has changed. Before go-live of feature, it has to follow certain coding standards so that it remains maintainable, reusable and scalable; hence design pattern implementation done. Agree on design patterns should be introduced in initial phase of development but whole team does the other way and that's the pain and forced me to get views of others in community.
    – Maheep
    Nov 4, 2011 at 8:39
  • How long are you typically working on such a POC before you start refactoring it? Nov 4, 2011 at 8:46
  • 3
    I wrote 3 proofs of concept. They are all still in production. Nov 4, 2011 at 14:13
  • 2
    @Maheep, what you're calling a proof of concept I'd call a prototype.
    – Caleb
    Nov 4, 2011 at 19:31

12 Answers 12

12

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.

4
  • +1: The distinction is important to be known from the get-go. If it's supposed to be throwaway - throw it away. It probably shouldn't even be in source control. Nov 4, 2011 at 20:08
  • Very nicely put, @Carl. What I was referring to in our project is the evolutionary prototype.
    – Maheep
    Nov 7, 2011 at 4:20
  • @Maheep then you should probably (based on your description) take greater care during its initial construction to keep it up to your organization's standards. Nov 7, 2011 at 15:48
  • Pragmatic Programming covers this as well. calling throwaway prototypes prototypes and evolutionary ones 'tracer bullet software': stuff designed to be small and test out ideas, if it works than follow through with the existing code, if not then you can throw it away without much cost
    – GSto
    Nov 7, 2011 at 19:52
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.

4
  • As you said refactoring is accessory to make code maintainable and reusable. But the question is "is it OK to do this after doing a "alpha/beta" level of code development or more time shall be spend initially?
    – Maheep
    Nov 4, 2011 at 5:10
  • 2
    @Maheep, again, it depends on your team. If you produce reasonably maintainable code in your "Quick mode", no problem, right? If you spend all your time refactoring, you need to figure out if that's because the "quick mode" code is crap, or if you're over-refactoring.
    – bdonlan
    Nov 4, 2011 at 5:11
  • I really, really hope their refactoring is more than just "naming standards"
    – CaffGeek
    Nov 4, 2011 at 17:54
  • @Chad, it's what it sounded like from reading the OP's post - but who knows? I can't say without seeing what they're doing
    – bdonlan
    Nov 4, 2011 at 21:18
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.

3
  • where I work, the POC is often a requirement to get a contract for the final version and is demanded to fully implement partial functionality (say a subset of the screens or messages the full system should handle), thus be more than just a quick sketch type thing. It IS the full system, just incomplete.
    – jwenting
    Nov 4, 2011 at 10:49
  • 1
    @jwenting Then you are missing most of the value of a POC. If you can't just throw it together in a short time, you're investing a lot of resources in something that might well get thrown away (why I prefer "test" of concept to "proof"). If it needs to be production quality, stop thinking about it as a POC. Nov 4, 2011 at 16:59
  • I know, Carl. We therefore treat the POC as just version 0.9 of the core of the final product for such projects. And might make some internal prototypes of specific areas to experiment with, if there's time, that get discarded (or at least not incorporated into production code) afterwards.
    – jwenting
    Nov 7, 2011 at 7:07
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.

5
  • The thing is, considering what Maheep said, they are not "building one to throw away", they are starting from the POC to transform it into the production version. This is somewhat different, depending on how much refactoring is needed and how much time they have, some little hairy things due to the POC design could be left in the final product. Nov 4, 2011 at 9:22
  • I've never worked in an environment where build one to throw away was an acceptable working practice. Some may see it as short-sighted, but it's a lot easier to justify refactoring than starting again from scratch.
    – Mark Booth
    Nov 4, 2011 at 10:46
  • Yes, there is only a semantic difference between "throwing away" and "refactoring it". I prefer building new a classs from scratch but copy-paste any useful and correct code from the POC into the new classes. If you really "throw away" your old code and start all over , you are doubling your work and probably re-making mistakes which you had already solved in the POC. So "throw away" doesnt necessarily imply deleting your code and starting with a blank page, it just implies that you use your PoC experience to make a good design, rather than waste time trying to refactor a really bad design.
    – DPD
    Nov 4, 2011 at 10:49
  • 1
    @mark Booth: Managers will definetly resist "build one to throw away" because they see it as an unnecessary waste of time( just like pair programming). In fact, I am rather surprised that POC is a standard process in Maheep's team! But like I have mentioned in my above comment , it is only a minor difference. To come back to Bruce Eckel's comment, he doesnt really say "throw it all away" but that you "you may still throw part of it away, but because code is encapsulated into classes, you will inevitably produce some useful class designs"
    – DPD
    Nov 4, 2011 at 10:59
  • 1
    @DPD So much of having a good non-technical manager vs. a bad one is how technical people communicate a message and how they convey an issue. Some developers can very easily convince a manager that a prototype is too rough but a much of it can be reused within the product. Some just don't understand that words like "refactor" and "rewrite" make them uncomfortable. It is all in how the message is conveyed even though technically both are saying the exact same thing.
    – maple_shaft
    Nov 4, 2011 at 12:42
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.

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.

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.

1
  • 1
    long-term should always win unless you aren't serious about what it is you're doing or unless your a scam artist and your goal is to make a disgusting amount of money as quickly as possible and then grab your loot and bail before the consequences of your actions catch up with you and everybody else. Sounds a lot like Wall Street doesn't it?
    – maple_shaft
    Nov 4, 2011 at 14:28
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.

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.

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.

Not the answer you're looking for? Browse other questions tagged or ask your own question.