Refactoring the DailyWTF

time to read 4 min | 643 words

It is not always that I quote the Daily WTF as an example of good code, but today's article is very interesting. Alex is talking about hard coding vs. soft coding. Where as hard coding means moving things into code, and soft coding means moving things into configuration, rule engines, business integration layers, etc.

I have seen systems whose configuration literally dwarves the complexity of the system itself. The system can literally do everything. My canonical example to this is that I once need to build a program that reads a file and send it to a web service. The program should have been generic, so it was. At a boring integration session, I configured it to be a web server as well, just because I could.

The example given for bad code in the Daily WTF article is this:

private void attachSupplementalDocuments()
{
  if (stateCode == "AZ" || stateCode == "TX") {
    //SR008-04X/I are always required in these states

    attachDocument("SR008-04X");
    attachDocument("SR008-04XI");
  }

  if (ledgerAmnt >= 500000) {
    //Ledger of 500K or more requires AUTHLDG-1A

    attachDocument("AUTHLDG-1A");
  }

  if (coInsuredCount >= 5  && orgStatusCode != "CORP") {
    //Non-CORP orgs with 5 or more co-ins require AUTHCNS-1A

    attachDocument("AUTHCNS-1A");
  }
}

And you know what, this isn't that bad of a code, certainly better than the alternatives paths that Alex has shown. It is still not good code, however.

The main issue that I have is that this method violates the SRP principal. I have three separate rules in this method, and three separate reasons to want to modify it. If given such a task, I would have refactored it to:

public interface ISupplementDocuments
{
    void Supplement(Policy policy);
}

Where each if statement in the above code is a class that implements this interface. Now, the attachDocuments method looks like:

private void attachSupplementalDocuments()
{
    foreach(ISupplementDocuments supplementer in this.supplementers)
         supplementer.Supplement(this);
}

Now I can make use of IoC in order to gain both benefits, clear cut code, and flexibility in deployment and runtime. The end result is well factored code, that can be easily understood and worked on in isolation.