Wednesday, September 12, 2012

How the Bystander Effect is Ruining Your Code

Source: Abu Badali, CC 2.5, via wikimedia

In 1964, for thirty-five long minutes, thirty-eight citizens of a respectable Queens neighborhood watched as a twenty-eight year old woman named Kitty Genovese was brutally raped and murdered. Not one person phoned for help.

The Bystander Effect

This story illustrates an unfortunate property of 'The Bystander Effect': The probability that somebody will render assistance decreases as the number of people increases.

As software engineers, we see the bystander effect in action every day. If your codebase is of any reasonable size and age, you are likely to have problems such as lack of encapsulation/separation of concerns, complex (or just plain wrong) class hierarchies, methods that are so long that they read like a chapter in the latest Stephen King novel, untested code, broken tests — and nobody does anything about it.

Causes

The root of the issue is lack of ownership. We assume that somebody else will fix the problem. In the case of our codebase, we may be apathetic because "it's not my mess". That's the problem with us software engineers: we don't want to fix problems caused by other engineers. The attitude of "it's not my mess" prevails.

Oh, but is it ever your mess.

Negative Externalities

Economists speak of something called 'Externalities'. That's a fancy way of saying that person A gets the benefits of something and person B pays for some or all of the cost. As person B, you will eventually need to modify that horrible class that person A wrote. You'll wish it were better designed. You'll wish you had functioning tests. You'll end up doing more work just to make a simple change. Your boss will wonder why you can't perform a simple task in a timely manner. You pay the cost for somebody else's poor decisions — that's a negative externality.

A Culture of Ownership

Fixing the side-effects of negative externalities is simple: take ownership of the problem — whether you caused it or not. Who cares about who is responsible? Those people are likely long gone anyway. Still waiting for them to fix it? It's not going to happen. Assume that nobody except for you is going to make things better.

Once you do that, a culture of ownership starts to emerge. When those tests that you worked so hard to fix end up breaking, you're on top of whomever broke it because you have sweat equity.

Likewise, you start to get improvements in your codebase 'for free'. You open up a piece of code that previously had issues. You dread working inside of it. Your sense of dread soon turns to delight as you find that some kind soul has made the world a better place. All of this happens because somebody else felt a sense of responsibility. That's a wonderful thing.

Act! Now!

So how about it? Spend a day this upcoming week in a section of code that is like taking a tour of the wrong side of town. Commit a random act of coding and leave a comment:

/* 
JKH 09/12/2012 - Refactored poorly managed transactions. 
If this makes you happy, PAY IT FORWARD!
*/

17 comments:

  1. Changing TODOs to "TODIDs"

    ReplyDelete
  2. At some point the code has become so complex you daredn't touch it. Sure I might help, but when this goes live something WILL go wrong. If I haven't touched the code I can't be blamed.

    (I do wish that I COULD though)

    ReplyDelete
    Replies
    1. Yes, the last time I fixed a bug that I wasn't told to fix, it turned out there was another bug in a different function that was relying on this bug to keep working. I turned a hypothetical bug that nobody had noticed into a actual bug. Now if I'm not rewriting the whole section I don't touch it.

      Delete
    2. That's one of my favorite bugs: bugs that conceal other bugs. Definitely a good reason to keep your functional test suites healthy!

      Delete
  3. You could have explained real life bystanders with a less brutal example. Makes the programming issue under discussion trivial and inappropriate after that intro.

    ReplyDelete
    Replies
    1. Actually, that's the canonical example, but it should be pointed out that people did call the police, making it a quite questionable example...

      Delete
    2. Interesting. This wikipedia article points out that a study in 2007 contradicts the seminal New York Times article:

      http://en.wikipedia.org/wiki/Murder_of_Kitty_Genovese

      From what I can gather (I haven't read the 2007 study), the article calls into question the Times' insinuation that the witnesses observed the entire attack. It asserts that they each observed parts of it. It goes on to say that records of the earliest call are unclear - as often they are when so much time has passed.

      Delete
  4. I work for a fast-moving startup. My team acknowledges the code smell, bad practices and lack of test coverage that exists in our codebase. Getting it fixed isn't really isn't a matter of ownership; it's a matter of priorities. Business needs generally take precedence over our desire to create a perfect codebase. We almost never have the resources to delegate developers to the purpose of making the codebase better. However, when we are tasked to work on a part of the codebase that has these problems, the team certainly expects the code problems to be cleaned up as part of the new work. This expectation is enforced during code review. This results in cleaner, better code over time. Consistent code reviews and agreed-upon idea of what "clean code" means will result in increasingly better over time.

    ReplyDelete
    Replies
    1. Great points, Moxley! I think your strategy of cleaning things up while you're in there implementing a new business feature is a perfectly salient strategy to iteratively clean up your code base over time. I think a lot of us engineers think fixing bad code is an all or nothing proposition. As you said, businesses rarely have the appetite for large refactoring projects. Going about it as you propose is a great way to make things better over time!

      Delete
  5. http://www.ncbi.nlm.nih.gov/pubmed/17874896

    ReplyDelete
    Replies
    1. I wonder how accepted the work in paper is? I suppose the Genovese story has had 40 years to work through popular culture, including psychology textbooks. Revising that story in the mind of the public is going to take time.

      I first encountered the story while reading Freakonomics - and certainly accepted the story there due to the credibility of the author. Of course, that book was published in 2005 and this paper wasn't released until 2007.

      There have certainly been other equally horrific examples of the Bystander Effect. If I had known that some parts of the story were questionable, I would have, of course, used a different example.

      I'd be curious to read the paper. I can't figure out how to read anything but the abstract in the link you provided.

      Delete
  6. Nice article. Please change your blog engine to one that allows us to cleanly print your posts.

    ReplyDelete
    Replies
    1. I'm glad you enjoyed it! I'll give a look and see what the blogger platform can do with respect to clean printing. I know they have a slick mobile view - surely they offer a similar functionality for printing.

      Delete
  7. I tried, printing is quiet okay w/ Chrome into PDF.

    ReplyDelete
  8. Some good points, although I don't believe you have to tie code _ownership_ to "Ordnung". I've worked at places where code ownership was explicitly disallowed in order to _encourage_ people to touch/clean-up/improve any piece of code they come across.

    Put another way: if only the owner is allowed to improve his code, then each module has an upper-bound to its level of cleanliness - that of the owner's.

    ReplyDelete
    Replies
    1. Good comments! I didn't so much mean that only one person was allowed to touch/change the code - although that is one possible implementation: to have a gatekeeper of sorts (the way that Linux Torvalds manages the linux kernel). It's more that people should feel a sense of responsibility to fix issues - whether they be design issues, test issues, etc.

      I think it is great that you worked somewhere that had a culture of encouraging others to 'get their hands dirty' in order to improve the quality of your shared code base!

      Delete