This article is Part 7 of 11 in a series about Habit of a Solid Developer.
- Part 1 - Introduction
- Part 2 - Automatically Enforce Project Conventions
- Part 3 - Self Prescribed Code Reviews
- Part 4 - Git Dance
- Part 5 - Update or Add Documentation while Reading Code
- Part 6 - Dig a Little Deeper
- Part 7 - (current) - Changes Should be Taken with Baby Steps
- Part 8 - Podcasts
- Part 9 - Rapid Feedback
Have you ever made some code changes and while in the process of making those changes realize you need to change something else, which leads to changes to that thing over there and then again up there, and down here, and over there and since we're in here and I've been meaning to tweak this well... and paused to realize you forgot the original goal of why you are even looking at this module of code? No never? (well I have).
git reset --hard and start over :)
If you're one who likes to apply the ol Boy Scout rule of
Always leave the campground cleaner than you found it to your code, just don't, at lest not yet. While I'm a big fan of cleaning up those legacy areas of code that just need a good sweep up, the approach taken here needs to be handled with care. I'm also referring to code that is likely covered well with automated testing.
Before you go around making a bunch of cleanup changes, fixing formatting, changing variable names, general cleanup. Accomplish a tiny part of your overall objective and commit just that change.
If you see other things along the way, take note and come back to them later. Or if, like me you can't help yourself, just don't check all of those changes in at once. Use something like
git add -p to segregate your code commits into tiny topical changes.
If the job is to
rename a variable, don't also
fix spelling, format code, extract method, etc.... Save those other changes for different commits.
But what if you don't know what you're planning to change?
Sometimes, it's good to go off and spike a big swath of changes just to get an idea how much impact a refactor could have on the architecture or project as a whole. Prototype something to get a good picture of whether a change is possible or not or to see how many coupled items need to be adjusted along the way.
However, you go into it knowing you will likely just undo all of your changes all together with the goal to surface more knowledgeable and either:
A) determine that it is a do-able change and should or should not even be attempted in a proper fashion B) or you've uncovered some challenges that are not easily overcome and require more thought or prior preparatory refactorings.
Use TDD as a forcing mechanism to small changes
TDD (Test Driven Development) is a great way to take as tiny a step as possible. With this approach, you can write a test, make it pass (consider that a change) and possibly check it in to source control. One test at a time ensures that you're taking baby steps along the way to solving the bigger problem(s).
Baby Steps also when Debugging
Taking baby steps is also important when debugging. Running around the codebase changing X, Y, and Z just to see if you can fix a bug will often times get you in a bigger mess than the original bug you tried to fix. Making one change at a time, verifying the bug, then the next change is quite often a better approach. So consider going slow and taking baby steps.
It doesn't matter if you're making project-wide architectural changes or surgical bug fixes, if you can, try to take baby steps, commit the changes and verify each change along the way. It may feel like you're going slower, but in the long haul you may actually save time.
Happy Baby Steps!