Refactor to Clean Up Before Moving On

Of course, the best time to refactor code is while it’s fresh in your mind, right after having worked with it. Once I get a feature to work, I go back and think about how I can make the code easier to understand. I’ve done this so often that it’s natural for me, almost of reflex.

Cleaning up code at this phase generally involves changing names of methods and attributes to more clearly state their purpose. Naming is my first line of defense in communicating what my code does. I want my names to be clear but when I’m in the process of discovering an implementation, I may not be as tuned in to refining what the name should actually be. Once I have an implementation that works then I’ll go back and see if I need to clarify any of my names.

Another cleanup activity that I’ll do at this point is to extract small methods from larger methods. I extract methods because it gives me the opportunity to name little bits of functionality instead of describing what I’m doing in a code comment. I find that if I can name some functionality, that it’s useful to wrap that functionality in a method with that name. I do this instead of using block comments in code because it makes my code more expressive. I want readers to read my code and not focus on reading comments.

Once I get a feature working as I want, instead of writing up what I did in a comment or external document, I go back to the code and see if I can let it tell the story, again by using good intention revealing names for the methods and attributes letting them say what the code is doing.

I want the code itself to say what it is doing but oftentimes code cannot say why it is doing what it is doing. To express why our code is doing what it is doing we often use block comments. This is the good use of comments whereas when we use comments to say what the code is doing we are just repeating ourselves from what the code says. Instead, I rather make the code clear and then I won’t feel like I have to have a comment saying what the code is doing. This will eliminate most of the comments in code and reserve them for only expressing the unexpected or for providing context around a large block of code.

The other thing that I will take a close look at when I have an implementation working but before I move on is to make sure that I don’t have any unnecessary dependencies. I want the dependencies in my code to represent real needs and I want to inject them into my code so that when I’m running tests I can inject test doubles or mocks instead. I want to try to avoid using singletons or service locators or other global states so that my software is as independently verifiable as possible.

Ideally, before moving on I want to make sure that I not only have clean code but also that I have good tests that express the intention of the code that I just built. Once I have these things I feel comfortable moving on.

Note: This blog post is based on one of the “Seven Strategies…” sections in my book, Beyond Legacy Code: Nine Practices to Extend the Life (and Value) of Your Software.

要查看或添加评论,请登录

David Scott Bernstein的更多文章

  • Green Tests and Red Tests

    Green Tests and Red Tests

    In practice, I found that there are times that I want a bit more test coverage than I get from just doing test-first…

  • Radiators and Silos

    Radiators and Silos

    In the old days of corporate America, the way you got ahead was through hard work and perseverance. You strove to…

    1 条评论
  • Makers and Menders

    Makers and Menders

    I’ve been getting back into some research interests of mine that require data acquisition from a variety of sensors so…

  • Core Developer Practices

    Core Developer Practices

    Every field of engineering has a core set of practices that they follow and software engineering is no different. But…

    1 条评论
  • Still XP After All These Years

    Still XP After All These Years

    Are you humming in your head Paul Simon’s “Still Crazy After All These Years”? I am. And it does seem crazy.

  • The Importance of Continuous Integration

    The Importance of Continuous Integration

    Perhaps the most important yet easiest to implement of all the software development practices in Agile is continuous…

  • The Importance of Technical Practices (Again)

    The Importance of Technical Practices (Again)

    Software development has undergone many revolutions over the last few decades. The way we build software today is…

  • Summary of Seven Strategies Series

    Summary of Seven Strategies Series

    I finished my “Seven Strategies” series of 72 blog posts with seven strategies for implementing each of the nine…

    1 条评论
  • Refactor to Learn What Not to Do

    Refactor to Learn What Not to Do

    One of the things that I was not expecting when I started refactoring other people’s code was that I started to see…

    4 条评论
  • Refactor to Redesign When You Know More

    Refactor to Redesign When You Know More

    One of the reasons that I’m such a proponent of doing emergent design or just-in-time design, is that this is how we…

    2 条评论

社区洞察

其他会员也浏览了