---
title: Refactor Until You Feel Almost Comfortable
teaser: Duplication is cheaper than the wrong abstraction.
tags: good code
author: Tute Costa
published_on: 2015-12-15
---

How do you know when you’ve refactored enough and when you’ve refactored too
much? I asked [Sandi Metz] about this once; here is a paraphrase of her answer:

[Sandi Metz]: http://www.sandimetz.com/

> Refactor until you feel you are one step behind the solution you want. Avoid
> your comfort zone. And while you might see extractions that would probably get
> you to a better design, don’t apply them until you see the need two or three
> different times. Remember that duplication is cheaper than the wrong
> abstraction. The best refactors will then naturally arise from the repeated
> inconveniences, instead of from unbacked ideas of what could potentially be
> better.

## Always be refactoring

I became a fan of applying refactoring techniques after seeing how it made two
teams in my previous company more reliable and productive over the span of two
months. I read about [Design Patterns], [Refactoring Techniques and Patterns],
[Software Design], subscribed to resources on Rubyisms like [RubyTapas] and
[Upcase]. I read countless blog posts on different ways of solving problems.
These teams continued to ship features without any interruption while I
iteratively applied design improvements to the codebase.

[Design Patterns]: https://en.wikipedia.org/wiki/Software_design_pattern
[Refactoring Techniques and Patterns]: http://c2.com/cgi/wiki?RefactoringPatterns
[Software Design]: https://en.wikipedia.org/wiki/Software_design
[RubyTapas]: http://www.rubytapas.com/
[Upcase]: https://thoughtbot.com/upcase/

Although a desirable outcome, refactoring is not only about the aesthetics of
your code. It’s also about sharing the understanding of the problem we are
solving and how our software helps to solve that problem. With better
understanding, we can more easily read and change the code, and we can even
identify dead code to remove.

While thinking twice about certain portions of our software, we might discover
new edge cases and bugs we haven’t seen before and opportunities to improve
performance.

When source code is self-explanatory, a team can loosen its dependence on tools
and processes meant to improve cross-team communication. Project management
applications, Iteration Planning Meetings (IPMs), and vocabulary dictionaries,
for instance, are not as necessary when developers speak the language the
business owners speak.

Sometimes we are forced to refactor before adjusting any functionality in our
project. Steve Freeman proposed dropping the “technical debt” analogy for
[“unhedged call option”] to better denote the fact that we may lose control of
our software before we can iteratively “pay off our debt”. We might then need to
[refurbish the codebase].

Refactoring is engaging and fun, too. I would refactor _all day long_ if it
_always_ made sense.

## How much is too much?

[refurbish the codebase]: http://java.dzone.com/articles/code-refurbishment
[“unhedged call option”]: http://www.higherorderlogic.com/2010/07/bad-code-isnt-technical-debt-its-an-unhedged-call-option/

Extracting [methods] or [classes] from high-churn [god objects] is almost always
a step forward.

Rewriting a class that is rarely used to make it more open for extension might
be fun but very unlikely to reap benefits both in the short and the long term.
Such a refactor can (and probably should) be avoided.

[methods]: https://sourcemaking.com/refactoring/extract-method
[classes]: https://sourcemaking.com/refactoring/extract-class
[god objects]: https://en.wikipedia.org/wiki/God_object

As Joe Ferris said in [our blog post] and [“Ruby Science” book], extracting
classes decrease the amount of complexity in each object but increases the
overall complexity of the application. Extracting too many classes will create
extra indirections that developers will have to navigate.

[our blog post]: https://thoughtbot.com/blog/how-much-should-i-refactor
[“Ruby Science” book]: https://gumroad.com/l/QoGA#

Every class also requires a name. Introducing new names can help to explain
functionality at a higher level and facilitate communication between developers.
However, introducing too many names results in vocabulary overload, which makes
the system difficult to learn for new developers.

My answer to “how often should we refactor” is “almost always”. I find
over-refactored code to be an uncommon problem, whereas overloaded code can be
found around the corner. Trying to improve the design of our software once it
has rolled downhill for a few months is too hard, while it’s easy to stop
refactoring once we’ve seen enough.

If you apply new abstractions only in response to pain and resistance, you’ll
end up with the right number of classes and names for your application and team.
Go forth and refactor, until you feel _almost_ comfortable.
