Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

On the fear of re-factoring code

by deorth (Scribe)
on Oct 04, 2007 at 08:49 UTC ( #642596=perlmeditation: print w/replies, xml ) Need Help??

At 1pm today I looked at a piece of code I had written last week.

It was fully functional, but not as optimal as it could (or should) be. It wasn't nice to other groups resources, and it had grown somewhat gnarly and untidy even after perltidy's magic.

So I was faced with the choice of whether or not to refactor/rewrite the code, based on what I'd already learned about the problem.

Now, for me at least, this code was complex. It dealt with data structures that were tough for me to get my head around. So, rewriting it actually caused me a certain amount of fear... what if I got halfway through and discovered I'd made a bad choice ? What if it didn't make any difference ? Oh my god this code is untidy, the design is clearly flawed..etc...etc...

The point is, taking the step to walk past that fear and refactor the code was one of those choices that became easy once I decided to do it.

12 hours later (well, maybe 5 hours of coding) the program is shorter, good friends with Devel::SmallProf, and has taken a cut in runtime of a little over 50%. The subroutines are better structured, the data structure is clearer, and testing it is similarly easier.

I think this is the first time I've felt that fear, and wondered if anyone else had ever had the same epiphany ?

Replies are listed 'Best First'.
Re: On the fear of re-factoring code
by Mutant (Priest) on Oct 04, 2007 at 09:29 UTC

    The key to overcoming fear of re-factoring (which is a reasonable fear to have) is having a good unit test suite that you're confident in. One of the code bases I work on is pretty poorly factored, and the unit test suite is not much better. There have been one or two times where I've made what seemed like perfectly reasonable and logical refactors, only to find I'd introduced a bug elsewhere in the app. I'm now extremely cautious of the code base, and will take a very conservative approach to any change I'm making.

    At some stage (since it's possible large scale changes may need to be made to this app), I plan to re-write the test suite from scratch. At the same time, I'll hopefully be allowed to refactor the code base.

    I certainly wouldn't want to refactor without that safety net of the test suite. Once a code base reaches a certain level of complexity, it's impossible to keep every edge case, scenario, possibility, etc. in your head. That's why we have computers to take care of those things for us.

Re: On the fear of re-factoring code
by samizdat (Vicar) on Oct 04, 2007 at 13:47 UTC
    I think my fear of refactoring goes up exponentially with the number of functions and modules I'm dealing with. Usually, in my case, however, I'll write my first pass as One Big Long Linear Glob With Lots of Amoeboic Branches, so the fear doesn't show up until I feel the need to refactor a _second_ time. :) That fear induces a healthy sense of responsibility to refactor correctly the first time... ;-]

    I think the most important thing to remember when refactoring is that you should always re-design to make your code fit the structure of the problem you are solving, not just to re-use code or shrink the size of the code. It's important NOT to mix refactoring and optimization, in my opinion! Doing that is a recipe for disaster. Current machines are fast enough that there's rarely a need to get tricky any more.

    I spend some time thinking about structure, order, and flow in code, once I've seen my first pass run a few times. I deal a lot with embedded systems and system-level coding with sockets and daemons and data i/o, so once I've gotten it running, I know where my tight spots are going to be. I map out the subsystems and the transactions that are necessary, and examine my message protocols for completeness, robustness, and flexibility. Within each subsystem (or daemon, or object), there's also usually a set of states which can be identified, and rules for transitions. Once I've gotten to this level of detail, I look at all the places where I can replace code with data structures used repeatably. Be careful to do this in ways that make sense to someone looking at the big picture of your project, and name things appropriately, both the data bits and the code functions that read them.

    Finally, and this is especially important with object-oriented programs, I distinguish between the 'initialization' and 'running' phases of the code. It's a natural tendency in OOP to create objects when you need them, but it's usually much smarter to build what you need once, prepare them completely beforehand, and then cut them loose. Doing this leads to much more predictable run times and far fewer surprises once the program is set free into The Real World. :D

    Don Wilde
    "There's more than one level to any answer."
Re: On the fear of re-factoring code
by toolic (Bishop) on Oct 04, 2007 at 14:44 UTC
    As far as alleviating fears goes -- and I know this is stating the obvious -- using a version control system would be 2nd on the list after a good test suite, as Mutant has so eloquently pointed out. If I really botch the job, or if I discover half way through that I wasn't as clever as I thought I was, I know that I can always go back.

      Actually I'd put RCS and test suit in the other order - RCS first. Going back in time is much harder that tacking on a test suit at some point in the future. Indeed, with an RCS you can retrospectively write the test suit against the original code even after the code refactoring is notionally complete.


      Perl is environmentally friendly - it saves trees
Re: On the fear of re-factoring code
by erroneousBollock (Curate) on Oct 05, 2007 at 01:48 UTC
    I frequently refactor my code and legacy code. Why should I be scared of refactoring ?

    I see refactoring as analogous to balancing my budget. Inevitably expenses are added, so I'm always looking for strategies to make it leaner. If I don't refactor code, I'll likely go "overbudget" - the code will be cost-prohibitive to maintain.

    The time I find best to start the refactoring process is the day after I get the code passing all tests; I still understand all the nuances of the problem-space, and I still remember the reasons I used particular flows and structures. At that point I comment the code with data-flow and reentrancy assertions and write tests to reflect those assertions, then fiddle until the code passes the existing unit tests and the new assertions.

    1 week after that, I go in as if I'd never seen the code. I do speed and memory profiling. I try to imagine various new scenarios for use of the code (in whole or in part).

    If the code needs refactoring for efficiency, I do it as a matter of policy - by that point I've already done most of what's necessary to make such a refactoring successful.

    If the code could be refactored to make it more flexible for re-use, I examine my schedule to see whether the refactoring is likely to take up more time than I have available in the short term. If I don't have time, I'll re-evaluate again in 1 week. Otherwise... refactor!.

    I hope this exposition has not been overly boring.

    -David

      A reply falls below the community's threshold of quality. You may see it by logging in.
Re: On the fear of re-factoring code
by Herkum (Parson) on Oct 04, 2007 at 13:19 UTC

    I used too, one job I started was fixing Perl code and the code they had was complicated and hard to understand. After a while I figured it out, The code was crap! Once I realized that, I was less worried about making changes. Anything I was going to do was an improvement.

Re: On the fear of re-factoring code
by lima1 (Curate) on Oct 05, 2007 at 09:30 UTC
    Working on legacy code is never fun. The problem is often that it works more or less, so your boss (or your rational alter ego) won't agree spending weeks on (re-)writing a test suite. Just try to improve the code slowly, make sure that you don't make things worse. Run Devel::Cover once a week, use Test::Perl::Critic::Progressive.
Re: On the fear of re-factoring code
by badaiaqrandista (Pilgrim) on Oct 05, 2007 at 00:34 UTC

    I do have fear when I see a bad code that is ripe for refactoring, but I think the decision should be based on cost-benefit-analysis, not fear.

    So when I see a code that needs refactoring, but refactoring would not add any significant benefit to the whole project, I would not do it.

    On the other hand, when a code is so complex but refactoring would gain much benefit in terms of maintenance, less bugs, or performance, I would go for it, even when I'm afraid it would break it. It also very much depends on the cost of the breakage.

    (But sometime you wouldn't know what benefit you will/will not gain until you finished doing it, that what makes the fear, I guess)

    -cheepy-

      Agree. Bad code does not always worth fix. Programmers have itch hands, but you can always spend your time do something better. If the bad code works, just leave it.

Re: On the fear of re-factoring code
by Firefly258 (Beadle) on Oct 06, 2007 at 05:49 UTC

    I'd suppose the need to refactoring the context of this dilemma is relative to how well the code satisfies given criteria and criteria do change over time. Knowing what to refactor, when and how much are also essential design criteria and should be constantly be reviewed over a programming project.

    Shying away from refactoring of code could lead the project (and program) to become unwieldy and perhaps also restrict evolution in ideas and concepts (useful mistakes, interesting discoveries, etc) along the way -- Generally, it would be wise to strive in finding a balance between flexibility of code and readability, programmer and program effeciency, scalability, etc -- too much refactoring towards optimization might leave the code inflexible to changing criteria over a project's lifetime.

    We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. - Knuth

    If it ain't broke .. refactor it. - Microsoft Windows




    perl -e '$,=$",$_=(split/\W/,$^X)[y[eval]]]+--$_],print+just,another,split,hack'er
Re: On the fear of re-factoring code
by Cop on Oct 04, 2007 at 18:34 UTC

    Also depends on your environment, if in your environment, you can easily be criticized for small things, then everybody is scared, and no one will try any improvement.

    In your case, you cited so much benefits your refactoring brought, it certainly worth your effort. Congratulations!

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlmeditation [id://642596]
Approved by Mutant
Front-paged by mr_mischief
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others imbibing at the Monastery: (3)
As of 2019-08-24 09:31 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?