Presentation: Succession: A Refactoring Story
Share this on:
What You’ll Learn
- Learn how to breakdown refactoring tasks into smaller more manageable interactions.
- Understand better strategies for applying refactorings to your code.
- Hear about common patterns and anti-patterns learned from large numbers of developers attempting to solve common coding exercises.
Abstract
Refactoring sometimes devolves into an appalling mess. You're chasing a broken test suite, and every change just makes it worse. At other times it's a slow, controlled process culminating in dreadful design. This talk presents an end-to-end refactoring that demonstrates simple strategies to avoid such misadventures.
Duplication catches our eye, yet much of design is about encapsulating differences. Focusing on the bits that are alike leads to awkward abstractions. Focusing on meaningful differences provides a better outcome.
The talk explores a meticulous style of refactoring that Martin Fowler alludes to in his book:
> [The] rhythm of refactoring:
> test, small change, test small change, test small change.
If every step is safe, then the test suite should never fail. Taking this idea to its extreme results in an artificial but potent constraint: stay one undo away from green. This constraint, which can initially seem awkward and mechanical offloads a morass of details into the process—freeing your working memory and reducing cognitive load. This is a powerful approach to keeping your code deployable, even while making dramatic changes.
What is the focus of your work today?
At GitHub, we have a GraphQL and a REST API. I focus on the REST API (we have about 550 public API endpoints in the REST API and that keeps growing). Most of my team works on the GraphQL side of things. I mainly work on the guts of the API - the plumbing, performance, and consistency. Much of my work is around things like code reviews and making sure that we don't break backward compatibility (even when we wish we could).
What’s the tech stack that’s powering it?
Most of GitHub is running on Ruby on Rails. The entire API is a Sinatra app that's mounted inside of rails. It's probably 8 or 9 years old at this point. The newer code at GitHub includes Haskell, Go, and Python. We probably have some Java in the data science side of things. We also run a ton of JavaScript with Electron and Atom.
You’re giving a talk on refactoring. Why refactoring?
A few years ago, I started an open source project that gives people little exercises to do. One of the exercises was the 99 bottles of beer song.
For such a simple nursery rhyme, it has some surprising algorithmic complexity. Everyone was trying to tackle the design in a way to make it simpler, but everything just made it worse. I didn’t even know if there is a good solution until a friend of mine came up with something that was pretty elegant. We started working together on it. I would do the factorings to try to get from a basic simple design to one of her designs. From that experience, we eventually developed a refactoring and object-oriented design course. We then went on to co-write a book about refactoring and object-oriented design.
Another motivation was my observation that people do very odd things in the name of refactoring, and it doesn't always turn out well. When everything breaks, instead of backing out and trying something smaller or something different, they'll keep going down that path. Hours or days later everything is still broken, and they often end up having to throw it all away. Even if it does manage to work, you have 60 or 70 commits and now you don't know which of all those changes mattered. I've focused pretty hard on techniques for thinking smaller and finding paths where you can keep your tests green in a more controlled rigorous manner.
Who is the target audience for your talk?
Anyone who has hands on keyboard writing code. It could be frontend, or it could be backend, It really doesn't matter what language you're working in. The day-to-day techniques of how you might avoid making something fail will be different in different languages, but the basic philosophy of thinking in smaller steps is the same in all the languages I’ve worked in.
What are some of the specific refactorings you hit on?
A lot of them are so small that they're not worth naming. They're very tiny meticulous steps. But there are techniques along the way. One of the ideas that I talk about is the idea of shameless green (which Kent Beck mentions in Test Driven Development). He says get to green as quickly as you can, and then from there, getting to great. Don't be clever, don't be smart, write the stupid solution. When everything is working you can get clever, even though often you don’t need complex, clever code. Interestingly enough, sometimes we feel embarrassed by simple code when we shouldn’t.
Similar Talks
Tracks
-
Microservices: Patterns & Practices
Evolving, observing, persisting, and building modern microservices
-
Developer Experience: Level up Your Engineering Effectiveness
Improving the end to end developer experience - design, dev, test, deploy, operate/understand. Tools, techniques, and trends.
-
Modern Java Reloaded
Modern, Modular, fast, and effective Java. Pushing the boundaries of JDK 9 and beyond.
-
Modern User Interfaces: Screens and Beyond
Zero UI, voice, mobile: Interfaces pushing the boundary of what we consider to be the interface
-
Practical Machine Learning
Applied machine learning lessons for SWEs, including tech around TensorFlow, TPUs, Keras, Caffe, & more
-
Ethics in Computing
Inclusive technology, Ethics and politics of technology. Considering bias. Societal relationship with tech. Also the privacy problems we have today (e.g., GDPR, right to be forgotten)
-
Architectures You've Always Wondered About
Next-gen architectures from the most admired companies in software, such as Netflix, Google, Facebook, Twitter, Goldman Sachs
-
Modern CS in the Real World
Thoughts pushing software forward, including consensus, CRDT's, formal methods, & probalistic programming
-
Container and Orchestration Platforms in Action
Runtime containers, libraries, and services that power microservices
-
Finding the Serverless Sweetspot
Stories about the pains and gains from migrating to Serverless.
-
Chaos, Complexity, and Resilience
Lessons building resilient systems and the war stories that drove their adoption
-
Real World Security
Practical lessons building, maintaining, and deploying secure systems
-
Blockchain Enabled
Exploring Smart contracts, oracles, sidechains, and what can/cannot be done with blockchain today.
-
21st Century Languages
Lessons learned from languages like Rust, Go-lang, Swift, Kotlin, and more.
-
Empowered Teams
Safely running inclusive teams that are autonomous and self-correcting