Hey, It’s Denis. Last week’s stream was an episode dedicated to those of you who struggle with finding the time or permission to conduct any form of refactoring at work. We explored a few strategies that help you navigate a slowly moving legacy code-based that does not practice continuous integration.
Small refactorings that are safe without tests
Backwards-compatible changes—Separation from framework types
Structural refactoring of hard to read code—Gilded Rose Kata
Small Refactorings
Engineers require to build an intuition as to which activity is most beneficial for short-term and long-term. This can take decades of introspection, trial and error. The simplest way of building this intuition is to have finished refactoring and improvements done in a very short amount of time.
Here are a few key tips on how to tackle them to follow alongside the stream recording from above’s episode.
Hotkeys and focus 3 minutes
First things first. You’ll be looking at the code, taking a clear scope and making an improvement. You don’t want to be bogged down in details and distractions from social media, youtube, music, task boards, slack or emails.
Close it all down.
Open your IDE
Have a terminal or GIT window open
Find the incision point for your work
Choose a simple refactor:
Introduce/extract variable
Introduce/extract method
Move method
Add a field
Check your editor’s hotkey for this and use only refactoring tools
IntelliJ users may use the plugin Key Promoter XPerform the refactor using the IDE
Check for compilation errors and immediate eyeball issues
Go to your terminal and isolate with
git add -p
and commitYou can stop here, go implement the feature… or continue refactoring, go to 1.
Backward-compatible Type Change 7 minutes
This is best in mid-end and front-end applications where you are working tightly with a dedicated framework or ORM.
Why are framework-related changes hard? Your types will often mix together your own classes and objects with those of the framework. When you want to refactor such a system quickly it’s best to do it backward-compatible and remove it gradually in small steps.
The steps can take as little as 30 seconds, but it’s important you follow them to make sure you are correct at each step before breaking something. Remember, you’re in a low-time, no-test environment. You don’t want to waste time having to debug.
Introduce the property or method you want, make it optional (ie. needs a default value or nullable)
No removal of old properties (for now).
Identify how the old property can be “filled in" to default state from old behavior
(Optional) Add any new constants that may be necessary for this. Remember, we are refactoring, not adding features.
Extract the “fill in” procedure into a helper. It’s likely it will now live very close to the definition of the type (opposed to the usage). Check the stream for an example
Ensure everything still works.
Move the helper to the usage point and remove it from the definition
If this is a new method, move it from inside the class to outside where it’s used
If this is a new property, move it to invocation-point (or consumption) rather than declaration
Once at usage-point, you’ll notice the new and old version are side-by-side.
Replace the old usage scenario with the new one.
Now follow it backwards: check if the helper is still necessary, fill the new style by default.
Make the new property/method mandatory and the old one optional. Remove old one when replacing all usages.
Improve hard to read code steps of 2mins each
This one is for helping you navigate hard-to-reason-about code. A key test is when your editor or code health tool warns you about high (cyclomatic) complexity. These are not following a strict order.
Rather they are small, atomic mini-refactorings—tidyings as Kent Beck calls them.
Introduce plain english into expressions that don’t read naturally
Introduce a variable or extract a method
Replace a code comment with an appropriately named method helper
Identify and mark places of mutation. Code is executed for state-changed or state-transfer. Visually mark where that happens and look for patterns
Re-order, flip, merge or decompose nested or combined if statements to bring them in cohesion without interference. More on vertical vs. horizontal in Kent Beck’s article below:
—P.S.: Our book club chose Kent Beck’s book for January and February 2024. Kent was generous enough to join us for our closing call in January. Having the author join our reading group is a great honor, setting a high standard. Proud of all of our Tech Leaders’ Guild readers ♥️
Share this post