Sunday, September 26, 2010

Dependency Injection Part 0: The tragedy

Consider this simple Magic 8-Ball Simulator class, here's the UI:



and here is the code, reading it should take perhaps a minute.  Heck just read the Run() method.
Why does this class suck?

Simple, it is doing way too much work.  As our requirements change and we work on this class, we'll start to introduce bugs in unexpected places.

[Requirements Change]: We'd like to store the 8-ball messages in a flat-file database.

Can you honestly do that without the risk of breaking unrelated code like message output?  Imagine the following scenario:

You: "Yeah, so I was making changes to how the messages are stored and fetched and I broke the way they print to the screen."
Your teammates: "Hmm, OK". sheesh this guy cannot work on one feature without breaking something completely unrelated

Hey those two responsibilities are not related! So put them in different classes. In fact the code above has lots of responsibilities:
  • Message retrieval
  • Reading user input
  • Printing message and program output
  • Handling user-interactions via a lame read-eval-print (aka REPL) loop
Separate responsibilities, separate classes, separate reasons for changing code. This is the Single-Responsibility Principle, a grand and simple assertion that: There should never be more than one reason for a class to change.  In my experience, most programmers dismiss this principle as obvious, and yet cannot seem to follow it when programming.  In fact this kind of code is present in project's which I've otherwise been damn proud to work on.

Source code for this post, please only download it to shun it, and never speak of it again.

Let's fix this code

In the next post we'll see what breaking this class up entails.

0 comments: