March 2013 Archives

It's Not Refactoring, It's Untangling

| No TrackBacks
Recently, I was catching up with a former colleague.  He mentioned a service that I wrote years ago, and how it has since become known as the Career Killer.  Basically everyone who touched the Career Killer ended up leaving the company.  If the company wanted to have > 0 developers, the only solution at this point was to take a few months and refactor this service completely.

I have two things to say about this.  First, that code was at 85% unit test coverage when I left so don't go blaming me.  Second, this huge refactoring?  It's not going to work.

Every codebase has at least one component that is widely hated and feared.  It does too much, it has too many states, too many other entities call it.  When it comes time to pay down technical debt, you should definitely focus on this component.  However, if you have an incomplete understanding of this component and you stop everything to completely rewrite it, your odds of success are low.  That component, as scary and complex as it appears, is actually way more scary and complex than you think. 

How do you think that component got into this unfortunate shape?  Is it because the company hired a nincompoop and let him run wild in the codebase for years?  Or is it because the component was originally a sound abstraction, but its scope of responsibilities had grown over the years due to changing requirements?  (For the sake of my ego, I'm hoping the Career Killer is the latter.)  In all likelihood, this component arrived at its current, scary state via smart people with good intentions.  You know what you are right now?  Smart people with good intentions.  If you proceed with a big refactor, you'll trade one form of technical debt for another.

In order to truly pay this debt down, you need to untangle the complexity around the problem.  You need to spend time looking at all the clients calling this component.  You need to spend time talking with your colleagues, learning more about the component's history and how it's used.  You need to make a few simplifying changes around the periphery of the component and see what works.  Each week, you spend a little more time and untangle the problem just a little bit more.  Given a long enough timeframe, you'll eventually untangle all of the complexity and brought a teeny bit of order to the universe.

Practically speaking, what do you do here?  Rather than 3 full months on a complete refactor, spend 25% of your time over the next year.  It's the same time commitment either way, but with the 25% plan, you get time to analyze and plan.  You get time to untangle.

Ship It!

| No TrackBacks
Several years ago, I had a job that, at the time, seemed like heaven.  We were a new team building a new product.  We were using new technology: C# 2.0 (yes, people were once excited about major releases of C#).  We were using new techniques, like scrum and test-driven development.  It was greenfield development in every possible sense, except for the one where our desks would actually be situated in a green field.

I lived in this environment for a few years.  I learned a lot about software development, technical leadership, and how to build big systems.  Ultimately though, I think I wasted those years.  Why?  We never shipped.

Something magical happens when you ship software: your decisions suddenly have consequences.  You suddenly must consider trade-offs.  Hopefully, people suddenly care.  If they don't, you suddenly must correct that.

What's the big deal about decisions and consequences?  Any fool with a text editor can write code, but only an amazing few can code and make good choices around trade-offs.  That's the most valuable skill a developer can possess: the ability to make hard decisions.  (That's actually a great way to make career choices: opt for the place that'll let you make harder decisions.)  Like riding a bike or juggling chainsaws, the only way to get good at making hard decisions is by doing it a lot.  Each time you make one of these decisions, gather data and iterate accordingly.

When I was working on that project that never shipped, I felt like I was making hard decisions.  We had big meetings and loud arguments about things that seemed important at the time.  You can bet your sweet bippy that we came to conclusions on all sorts of things.  However, since we never shipped, we never got any data about any of the choices we made around things like architecture, code coverage, implementation decisions, featureset, and user interface.  Without that data, we had no way of knowing if we had chosen correctly.  Did we get better at making hard decisions?  Without users, how could you tell?

There was an easy solution to the problem I faced at that job: ship the dang thing.  That decision wasn't up to me, so I should've done the next best thing: join a different team, one that shipped a ton of code.  Even if the codebase is worse and the product is less interesting, find a role where you ship; it's the only way you get better.

About the Author

The Art of Delightful Software is written by Cody Powell. I'm currently Director of Engineering at TUNE here in Seattle. Before that, I worked on Amazon Video. Before that, I was CTO at Famigo, a venture-funded startup that helped families find and manage mobile content.

Twitter: @codypo
Github: codypo
LinkedIn: codypo's profile
Email: firstname + firstname lastname dot com

Categories