Sunday, August 18, 2013

But I already wrote it

A few weeks ago, we set out to implement a feature that enabled back office users to set a new rate ahead of time. With our analyst and the involved user being out of the office for days, we had to solely rely on written requirements. Two of us skimmed the documents, but didn't take the time to assure there wasn't any ambiguity - it looked trivial really. I went back to what I was doing, while my colleague set out to implement this feature. Going over the implementation together the next day, he had built something a lot more advanced than I had anticipated. While I argued that this was a lot more than we needed, we agreed to wait for feedback from our analyst to return from her holiday.

When our analyst returned, she confirmed that the implementation did a lot more than we needed. I suggested removing what we didn't really need. My colleague argued that he now already had put in the effort to write it, and we should just leave it as is.

I can relate to feeling good about freshly written code, but that shouldn't stop you from throwing it away. Code is just a means to an end; the side product of creating a solution or learning about a problem. If you really can't let go, treasure it in a gist.

In this particular scenario, one could argue that making the solution more advanced than it should be, isn't strong enough of an argument to make a big deal out of it. We're giving the users a little extra for free, right? 
I cannot stress the importance of simplicity enough; to be simple is to be great, perfection is achieved not when there is nothing more to add, but when there's is nothing left to take away, and all of that. Nobody likes bulky software. Nobody likes fighting complexity all day.
But by only considering the cost of initially writing it, you are also ignorant of the true cost of what appears to be a small little extra on the surface. Users, developers, designers and analysts alike have yet another thing to wrap their heads around. More code is not a good thing; more code to test, more code to maintain. Each feature, how small it may seem, needs to be taken into account when planning on new ones. Each feature, definitely an advanced one, makes the cost of training and support go up. The cost of implementing a feature is just a tiny portion of what it costs to support that feature through its entire lifetime.

Using this argument, I eventually succeeded in persuading my peer to dump the ballast. The real lesson for me however, is probably that how trivial it might have seemed, we could have ruled out any possible ambiguity in advance by using one of the various tools we have to our disposal; a smallish white board session or maybe pairing on some high level tests.

21 comments:

  1. The world wasn't built by removing unnecessary things.You should rethink your attitude that's my opinion

    ReplyDelete
    Replies
    1. Good products are completely void of unnecessary things.

      Delete
    2. "Everything should be made as simple as possible, but no simpler." - Albert Einstein

      Delete
    3. Nice opinion... ;) try explaining to a 90-year old why he can't just use his phone to call the way he used to... (without going through dozens of apps or extra buttons or ... )

      Delete
    4. Your idea of an "unnecessary thing" is another guy's "useful feature." I don't know what 90% of the features in a lot of the tools I use do, but I'd be pretty pissed if someone pruned part of the other 10% calling it unnecessary.

      Delete
  2. opc0de doesn't get the true cost of complexity, great post.

    ReplyDelete
  3. Every extra whiz-bang and whirlygig is another moving part that can break. It's also another potential avenue for security failure.

    Commit the code to keep it in the repository, but the extra bits should definitely be pruned out altogether in production code.

    ReplyDelete
    Replies
    1. Your analogy is incorrect. Code is static. It doesn't just break down one day like a car.

      Delete
    2. The code doesn't change, but there could be a hidden bug in the extra code that you just haven't found yet.

      Delete
    3. You would think that...

      Delete
    4. > It doesn't just break down one day like a car.

      The code doesn't change, but often the dependencies do. Libraries deprecate functions, that web service you rely on changes its API... Bitrot does happen.

      Delete
  4. From your post you assume more feature == more code. This is not always the case: sometimes the solution offered is more general, and with less code.

    So you need to *add* code (aka complexity) to *limit* the features.

    ReplyDelete
  5. ZeD is right. For almost all non-trivial applications, features does not correspond to code.

    Less code is not always better. More code can sometimes be more robust. An obvious example is security, where implementing a solution more than the customer really needs sometimes is necessary in order to avoid having unwanted "features" (that is, security holes).

    ReplyDelete
  6. The attitude that code is just a means to an end is a shitty attitude toward writing code, and will inevitably lead you to writing shitty code.
    The way you write good code is by loving good code. That's it.

    ReplyDelete
    Replies
    1. I prefer writing code that gets used over code that's beautiful. This doesn't mean I don't appreciate good code though.

      Delete
    2. You don't write code simply because you love writing code. You write code with a goal in mind. You always write code with a goal in mind. And there's nothing stopping you from loving your code or writing it beautifully.
      Ergo, your argument is invalid.

      Delete
  7. Great post and the correct decision, IMO. Bonus functionality is a prime example of substituting the developer's judgement for the customer's. That's not an example of professional behavior IMO.

    ReplyDelete
  8. Without knowing what feature was implemented, I can't really comment on whether this was the right call... but I just wanted to point out the hidden cost of your decision here.

    You just taught your colleague to never take the initiative to implement a features he considers valuable. From now on, he should consider himself to be a code monkey whose job is to accept the designer's vision, regardless of how short-sighted or limited it is, and produce a working program.

    Goodbye job satisfaction...

    I would have at least deferred the decision: wait and see if the feature actually requires additional maintenance costs, and decide *then* whether it's worth keeping.

    ReplyDelete
    Replies
    1. I try to stimulate initiative, but we should work *together* with analysts and business, instead of just delivering functionality we think is right.

      Delete
  9. What about testing? That extra feature probably doesn't have a test plan written for it and would be omitted by the testers. Users could then stumble on an unknown (and possibly undocumented) feature and break something.

    This is why any deviation from specs need to be discussed with everyone involved in the process!

    ReplyDelete
  10. You made the correct decision. And should the need arise for the 'extra' features, then there is always source control :)

    ReplyDelete