Monday, December 15, 2008

My English Teacher Would Be Proud -- Proper Language Is Still Important

My high school had one English teacher that was dreaded by all, Mrs. Koch. Mrs. Koch's classes were known to be tough. Most of my friends were accustomed to getting high grades, but this didn't happen too often in Mrs. Koch's classes. Over the course of two semesters, one student got an 'A' in one semester. Mrs. Koch took for granted that we knew the basics that we were supposed to know. For written assignments, she assumed that everything would be spelled correctly and there would be zero grammatical errors. Assignments were graded for content, but grammatical errors caused sever markdowns in one's grade. Language was important.

I am thankful to Mrs. Koch for nurturing a strong sense of grammar in me. Perhaps this is what I have always liked the strict syntax of programming languages. This may also explain why I like Behavior Driven Development so much. Language was critical in Mrs. Koch's class, and language is critical to understanding business software.

BDD brings language into what I believe is its proper place -- the forefront. Language allows developers to understand the business. Language allows the development team to communicate with the project sponsors and domain experts. The more prominent, clear, and accessible our language is, the more readily we understand each other. The more accessible the language is in the code base, the easier it is to understand what we are doing and why we are doing it.

This is why I like BDD so much. When I read through specifications, I can understand what the system does. The more natural the language is, the faster I can stop thinking about syntax and start thinking about the correctness of the system. Natural language also helps to engage the non-developers on the team. While I've watched our project managers look at Java code and guess about what the system is doing, its much easier for us to have a conversation without Java language constructs getting in the way. Likewise, the less we talk about exceptions, try/catch blocks, and if-else statements, the better. Instead, we prefer discussing how the system should and should not behave under certain conditions.

Case in point: Instead of, "The protected area should thrown an exception for unauthenticated users," I would prefer to say, "The protected page should require the user to be logged in." We shouldn't have to acclimate the business types to programmer speak.

Clear language also helps us identity when the design is going astray. One simple word is often a clue to me that a class has too much responsibility. That magic word is, "and." Here's an example:

Lets assume that we're developing a console application that takes in a relatively complex configuration file. The customer has told us that, when the configuration is bad, he wants to be notified in a variety of ways. Sometimes this process will be run manually, and he would like the operator to receive immediate console output for bad configuration. Sometimes, the process is launched automatically and unattended, so he would like configuration problems to be emailed as well. For a final good measure, he has also requested that problems be logged to the logging system we have chosen for the project. We'll assume that the logging and email services live behind a nice interface that is easy to test. We might, then, get a specification that looks like this

The ConfigurationHandler, when some configuration properties are missing and logging is configured and email is configured should log an error for the missing properties and send an email for the error and write an error message to the console.

Assuming that our logging and email systems are properly testable (injected somehow), the actual calls to those services could be a pretty small footprint in the production code. However, this is too much responsibility for the ConfigurationHandler. We see it logging, sending email, printing to the console and killing the process somehow. There are lots of "ands" in the specification indicating that perhaps too much responsibility has been given to the ConfigurationHandler.

If we look at the behaviors shown, they are all about reporting the error. This is when we notice that, perhaps what we need is one more concept called the ErrorService. We can hide all the emailing and logging behind that. So, we break out a new class and a new interface and we end up with the following specifications:

The Configuration Handler, when some configuration properties are missing should report the missing properties to the ErrorService.

The ErrorService should forward errors to the log file, email, and console.

There are still some "and's" there, but the responsibilities are better broken down.

Language is critical to understanding software. BDD helps bring language into more prominence. What does the language of your specifications tell you?

No comments: