Should one refactor while writing?

Started by
18 comments, last by mrbastard 11 years, 6 months ago
Sometimes I'm in a situation where I have an idea that I want to roll out immediately. I want to implement it, see how it feels, and make design edits from there. This is when I'm thinking about user experience instead of actual code. Unfortunately, when you know exactly how to do something, you often know multiple ways of doing it. There's a quick, ugly, embarrassing way, which can be done in 15 minutes, or the slightly more elegant, less embarrassing way that will make you think a little bit.

My first question is, do you guys often do the quick and dirty thing, and then go back to fix it later; or do you get a hold of yourself and make sure you get the job done well, first and foremost?

My second question is, what is your attitude about refactoring? I've heard Code Complete is good, and I've been recommended Refactoring by Martin Fowler, but I won't have the money for those books for a little while, and I think my question is specific enough to ask and expect reasonable answers. To narrow it down: Do you refactor while coding, or do you refactor after everything's done? I've always thought it might be good to take breaks during long projects to fix up what's there already before moving on, but I dunno. Could you guys share a little on that? Thanks.
Advertisement
The answer to your question depends on a lot of things but mostly
1. How big a job or time-consuming of a job is the re-factoring going to be?
2. Where are you in terms of deadlines and external commitments to getting stuff done.
3. How bad is what you have without re-factoring and how bad is it going to be to continue with it without re-factoring.

Generally, for hobbyist or personal projects you can do whatever you want but just be wary of the fact that constantly rewriting stuff in an attempt to make everything perfect and beautiful is a good way to never actually finish anything.

For non-hobbyist / stuff you are doing professionally, it's a different situation -- often the choice isn't yours to make when dates need to be hit and so forth.
Ideal solution: write up the perfectly designed code the first time in fifteen minutes.

It's half a jest, but seriously, good design is not very hard, and provides enormous returns for your effort. Good design is all about making your life easier. If you're spending more time designing and coding something "elegant" versus only coding something crufty, you're not doing it right.

[size="1"]And a Unix user said rm -rf *.* and all was null and void...|There's no place like 127.0.0.1|The Application "Programmer" has unexpectedly quit. An error of type A.M. has occurred.
[size="2"]

Anything is NOT done before you refactor your code.
I usually split coding to small tasks, after each task, I refactor for it.
Or I will refactor if there is enough code, eg. 1000 lines of code.
The small refactor is lower cost than big one (refactor after whole project is done).

https://www.kbasm.com -- My personal website

https://github.com/wqking/eventpp  eventpp -- C++ library for event dispatcher and callback list

https://github.com/cpgf/cpgf  cpgf library -- free C++ open source library for reflection, serialization, script binding, callbacks, and meta data for OpenGL Box2D, SFML and Irrlicht.

I don't refactor while in the middle of making changes, but yeah, I refactor when needed between changes or after changes.
I don't refactor for refactoring's sake, but only when the code is messy or will soon become messy through changes that refactoring could prevent.

As Geometrian says, it's best to write it clean the first time. My code usually is clean the first time, and only accumulates cruft over time from additions - that's when I refactor. Occasionally (but not too commonly), I need to refactor after writing it the first time because I had difficulty comprehending the first time through. I'm talking function-level refactoring, not architecture-level refactoring. I have to do architectural refactoring every so often because I'm still learning good architecture and make alot of mistakes there.

Code Complete is worth the money when you can get it.

My first question is, do you guys often do the quick and dirty thing, and then go back to fix it later; or do you get a hold of yourself and make sure you get the job done well, first and foremost?

This really depends on a number of factors:

  • Why are you writing the code?

    • Is this just a quick disposable test to find out if an idea works, or is it production code? If it's just a quick test that will be thrown away it's often best to simply get it working as quickly as possible, but production code should always be as clean as you're able to manage within any other constraints
    • Is the code part of a larger project and/or likely to be reused? Are you likely to need to adapt the code for other uses? When writing code that will be re-used, which you might need to re-purpose, or which will be part of a larger system it's important that you design it as well as possible. If you're writing a little script to automate a one-off task it really doesn't matter as long as it gets the job done properly.
  • Are you time limited? If you have a deadline to meet you might not have time to formulate and implement a better solution. Obviously if the "quick and dirty" solution is too dirty and will cause extensive additional problems or might not work correctly you'll need to try your best to get the deadline extended, but if it's going to work fine and won't cause a massive blow-out in some other area or at a later stage then it can sometimes be necessary to simply choose the solution that allows you to meet your deadline.
  • How "dirty" is the "quick and dirty" solution? As above, is it just a sub-optimal solution that will otherwise work alright, or are there serious problems with it?
  • Who will have to work with the code? If it will never be touched again it probably isn't overly important. If you're the only one who will have to work with it you might be comfortable with the less optimal solution for now. If others will have to work with your code then you probably want to put your best effort into the best/clearest design you are able to implement.


  • Do you refactor while coding, or do you refactor after everything's done?

    A bit of both if needed, although refactoring while coding can normally be kept to a minimum -- almost entirely eliminated once you're more experienced -- by designing properly in the first place.



    Do the best you can, but expect to make mistakes as you learn and grow as a programmer. It won't always be practical to fix all your mistakes if you want to continue to progress, but as long as you recognise and learn from them that's fine -- save perfection for when you're writing important code.


    ...and just to re-enforce what others have said, Code Complete is well worth the money once you've saved up.

    - Jason Astle-Adams

    Refactoring and feature additions should be in separate commits. This allows the definition of refactoring as a "behaviour preserving transformation" to be useful in a practical way beyond the immediate point of use - it's helpful information to have while regressing to find the source of a bug, for instance. If the refactoring is mixed with other changes it becomes much less useful.

    Ideally, I'd like refactoring tools in IDEs to work with version control to check in and revert as I refactor/undo - and potentially even branch when I start refactoring then merge when I'm done and the tests pass.
    [size="1"]
    When not working to a defined interface or protocol, I'll code a bit, get a good result, then analyze and (usually) re-write what I've written in an effort to make it easier to expand or to maintain, usually by identifying the generalizations that will make it flow better. Just as often, once I have something working, I'll then design a cleaner architecture that produces the same work, but with less spaghetti-coding. This holds true whether I'm working on terrain generators, machine-code assemblers, or data processing.

    I mostly work in Java these days, so Eclipse's refactoring tools are often leveraged to re-organize my namespace, especially moving inner classes out into their own files with just two clicks. Moving classes from one namespace to another with all references kept intact is always nice.

    When I do have to arrive at a specific interface, though, which is about half the time at work, I naturally have to work the same way we arrived at that interface spec in the first place; start at the goal, and problem-solve my way to the implementation that achieves it. This is generally actually faster than the other way, but because I won't always have progressively implemented versions along the way to the final product, it usually feels slower.
    RIP GameDev.net: launched 2 unusably-broken forum engines in as many years, and now has ceased operating as a forum at all, happy to remain naught but an advertising platform with an attached social media presense, headed by a staff who by their own admission have no idea what their userbase wants or expects.Here's to the good times; shame they exist in the past.
    I think that it's about striking the balance between being pragmatic enough to get things done to meet the deadlines and being disciplined enough to not sack clarity and good coding practices in favour of "I'll refactor this later" (which, of course, rarely happens when one has external forces dictating how much time one has to get things done).

    I'm a researcher myself so whilst I do work to external deadlines they are no of the frequency of, say, a professional programmer. The shelf life of my code (almost exclusively prototype applications) is very short so it's all to easy to write disposable "fire and forget" code as one is lulled into the false sense of security that such code is "one use only" and not worth exercising some discipline over. This lax attitude had cost me unnecessary (and precious) time on more than one occasion when an important deadline gets dumped on me at short notice.
    I've learnt through bitter experience that you should always start from a working, committed code base before attempting refactoring. As to the question of when to do refactoring... whenever it feels right. Seriously. If the codebase is all messed up and its eating away at you, spend some time cleaning it up. If its "ok", but not as elegant as it could be, but you're ok with that, then ignore it and work on other features.

    Sometimes refactoring adds nothing to the codebase other than piece of mind. Other times it spawns useful ideas you might not have had otherwise.
    [size="2"]Currently working on an open world survival RPG - For info check out my Development blog:[size="2"] ByteWrangler

    This topic is closed to new replies.

    Advertisement