Skip to content

Instantly share code, notes, and snippets.

@dsilfen-handy
Last active November 14, 2016 21:45
Show Gist options
  • Save dsilfen-handy/e0848f339e634efea6bd60dedba2b8d1 to your computer and use it in GitHub Desktop.
Save dsilfen-handy/e0848f339e634efea6bd60dedba2b8d1 to your computer and use it in GitHub Desktop.
Notes for Refactoring Ruby Chapter 2

Refactoring Ruby: Chapter 2

Principles in refactoring

What is refactoring?

  • Fixing code the second time around, because programmers rarely write good code the first time

Noun: a change to made to the internal structure of software to make it easier to understand and cheaper to modify without changing its observable behavior

Verb: to restructure software by applying a series of refactorings without changing its observable behavior

Refactoring to increase understanding

  • Refactoring to make the code cleaner, and make assumptions obvious
  • The less the reader of the code must remember, the better
  • Prevent software rot when code goes untouched for too long

Good design leads to rapid development

  • When code is extensible and well designed, it makes the addition of new feature easy, making overall development far quicker.

When should you refactor

  • Rule of three: the first time you do something, just do it. The second time, pause and make note. The third time, refactor.
  • Refactoring when the existing design does not allow you to easily add desired features and functionality.
  • Take the time to analyze the ROI of refactoring code whenever adding a new feature.
  • Even when an attempt at refactor fails to remove or simply code, it is still an important lesson for the team and must be taken into consideration in future projects.
  • If you often get bug reports around an area of code, it means the code is not clear enough to prevent bugs and should be refactored.

Why Refactoring Works

  • Programming not just for today, but for the future.
  • When yesterday's decisions don't make sense today.
    • Programs that are hard to read are hard to modify
    • Programs that have duplicate logic are hard to modify
    • Programs that require additional behavior that requires you change running code are hard to modify
    • Programs with complex conditional logic are hard to modify

What do I tell my Manager?

  • Stressing the quality aspect of refactoring
  • When there is no spare time, keep it from your manager?
  • If the fastest way is to refactor, it should be your first choice

Benefits of Indirection and Refactoring

  • Enables sharing of logic through multiple parts of the code
  • Intention vs Implementation, the intention is described by the public interface, and the private implementation is named in reference to that.
  • Isolate changes, when code is reused multiple times. When that logic needs updating, we only need to update it in one place
  • Encode conditional logic through polymorphic messages
  • Careful upfront design can suffer from incorrect assumptions. Refactoring as you go allows you to correct for new requirements.
  • On the other hand, when indirection offers no benefit, it can simplify the program to remove it. (Parasitic indirection)

Problems with refactoring

  • When changing interfaces, you can break your dependencies and cause errors.
  • When an interface is public & "published", you must maintain the old interface until old callers are using the new interface.
  • Avoid publishing public interfaces unless they are entirely necessary, they create a maitnence burden greater than their benefit.
  • Databases schemes can be tightly coupled to code, especially ActiveRecord models which makes domain objects that tie back to database tables.
  • Large infrastructure changes, like switching languages, frameworks or architecture can be very costly. Refactoring changes like this are possible, but at very high costs.

When not to Refactor

  • When a complete rewrite would be more productive
  • When time simply does not permit, if the deadline is approaching, refactoring may not be best for the business
  • Refactoring for academic purposes is the most costly form. Philosophically disagreeing with code does not mean we should Refactor it if the intention is still clear and the behavior is correct.

Refactoring and Design

  • Refactoring takes pressure off the initial design. If there were any bad decisions made the first time around, we can simply update them later.
  • Upfront design often assumes that changes down the line are costly because they take time, but we can compromise by having a "good enough" design, and fill in the blanks later.
  • When descisions can be postponed in upfront design, postpone them. You can Refactor later.

Refactoring and Performance

  • Having software that suits tuning, then tuning it towards performance.
  • Do not spend time making the program fast without clarify about what's making it slow.
  • Retune performance in codepaths that are often hit and yield the biggest gains.

Dean's Note

This whole chapter is operating under the assumption that the refactor will improve the quality of the code, however the road to hell is paved with good intentions. I can easily picture a scenario where teams attempt to refactor code but end up making it worse.

  • If a team is missing baked in assumptions about what the code does, but this is not clear until the code is in production
  • Underestimating the work required to improve quality, the team deploys a portion of their refactor. This can lead to duplicated logic.

These are not counterpoints against refactoring. We should not let perfect get in the way of better, but these issues should be acknowledged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment