The Single Responsibility Principle states that a class should only have one reason to change. Another possible title for this design principle would be the Single Reason to Change Principle.

Why is it important for a class to have a single reason to change and what are its benefits? One of the easiest ways to enhance the maintainability of a code base is to have it loosely coupled. In loosely coupled code, a change to one feature does not affect any other functionality. It is the opposite of spaghetti code where everything happens in one big method and changing how one functionality works very likely affects all the other functionality. And to get this loosely coupled code, each feature should be broken up into individual classes. If each class implements only one feature, then it only has one reason to change and when you change that feature you don’t have to worry about it breaking anything else in the code base.

A good example of a violation of the Single Responsibility Principle is having data validation and storage in the same class. Take a look at the code below as an example.

public virtual void Save(User user)
{
  if (string.IsNullOrEmpty(user.Name))
    throw new ValidationException("User name cannot be blank");

  using (var conn = new SqlConnection("connection string"))
  using (var command = conn.CreateCommand())
  {
    command.CommandText = "INSERT INTO USERS (Name) VALUES (:name)";
    command.Parameters.Add(new SqlParameter(":name", user.Name));
    command.ExecuteNonQuery();
  }
}

This code violates the Single Responsibility Principle because it performs two tasks: validating the object and persisting the object. These two responsibilities are orthogonal to each other and should be separated out to two classes since neither one affects the other.

Now that I have explained this design pattern, I want to give my opinion on its usage. I believe this principle is good to follow when designing applications but I don’t think it should followed to a T. I say this because I see some people take it too far. For instance, take for example the interface below.

public interface Modem
{
  public void Dial(string phoneNumber);
  public void Hangup();
  public void Send(string message);
  public string Receive();
}

Some would say the methods on this interface need separated out into 2 interfaces, one that takes care of the connection (Dial and Hangup) and another that takes care of the communication (Send and Receive). Personally I disagree. Yes, I can see how some could consider there being 2 responsibilities in this class, but then what is to keep the interface from being broken up into 4 interfaces, one for each method, because I could also see how Dial is a distinct responsibility from Hangup and Send is a different responsibility than Receive.

As far as implementing the Single Responsibility Principle, I personally advocate that there needs to be a sliding scale on how fine tuned the responsibilities are split out.

Before I expound on my position further, I need to introduce a term called responsibility group. A responsibility group is a set of responsibilities that correlate to each other in one way or another. The size of a responsibility group can be anywhere from large to small. The smaller the responsibility group, the more closely each responsibility correlates to each other, and the larger the group, the more loosely the responsibilities correlate to each other.

The smaller the application, the larger the responsibility group should be, and the larger the application, the smaller the responsibility group should be. The graph below shows a visual representation of what I’m talking about.

ApplicationResponsibility

I advocate this view as a result of my own experience. I volunteer my time at a non-profit organization where I have developed quite a few applications to help automate some of their administrative tasks. Many of these applications are quite small with less than 100 lines of written code. In these applications do I separate out the validation logic from the persistent logic? No, it’s not worth it. If I did I would very likely have more classes than I did lines of code. However, in my open source project (Linq to Excel) I have much smaller responsibility groups since it’s a larger project with many features.

One of the arguments for using this principle is making the code easier to maintain and add enhancements. But with small applications that serve a single specific purpose, it’s quite unlikely that they will change. And even if they do change and enhancements are added, the Single Responsibility Principle with smaller responsibility groups can be implemented by refactoring the code when the enhancements are added.

These are my thoughts and 2 cents worth on the Single Responsibility Principle. I know I do not follow the main stream of thought for this principle so I would love to receive feedback on my ideas on this principle. What is your experience with using this principle?

 | Posted by admin | Categories: Uncategorized |

Last week was the first time I used the jQuery javascript library and I must say I’m impressed. It has one of the simplest APIs that I have used which made learning how to use it quick and easy. In fact, I was able to write a custom plugin for it within a couple hours!

I would like to cover the business problem I had and how I used jQuery to solve it. One of the internal web sites at my company has a user rights management page where an administrator can control the individual rights on the site for each user. This page has a drop down list of all the employees which is used to give rights to a specific employee. The problem was the drop down list was not alphabetized and it contained over 1,400 employee names to choose from! It felt like finding a needle in a haystack every time a new employee was given rights.

The root cause of the issue was the use of a hacked together database view that returned the list of employees ordered by their full name. Database views are not supposed to have order by commands, but this one did and the website was expecting the view to provide the ordering. However, the view was not returning the employees as properly ordered. After some research it was found that the database optimizer figured that bypassing the view and using the data directly from the table was more efficient than going through the view, which meant that any code using the view would receive an unordered list of employees.

Once that was figured out I was able to add an order by to the sql command and the drop down list was now ordered correctly.

However, there is an acronym we often use at work as our motto: MISL (pronounced missile)

Make
It
Suck
Less

And only alphabetizing the list did not Make It Suck Less enough for me. It was still a pain the neck to scroll through the 1400 employee names in the drop down list.

My solution was to use jQuery to replace the drop down list with an auto complete text box that had the same value as the drop down list.

After finding an auto complete plugin for jQuery I was ready to implement my solution.

The first thing I did was hide the drop down list and add an input text box after it

$dropDown = $("#EmployeeDropDownList");
$dropDown.hide()
   .after("<input type='text' />");
var $autoCompleteTextBox = $dropDown.next();

I then retrieve the array of employee names from the drop down list and pass it as an argument to the autocomplete plugin

var dropDownItems = [];
$dropDown.find("option").each(function() {
   dropDownItems.push($(this).text());
});

$autoCompleteTextBox.autocomplete(dropDownItems);

I then subscribe to the blur event on the new auto complete text box to synchronize the selected value on the hidden drop down list with the value in the auto complete text box

$autoCompleteTextBox.blur(function() {
   var textBoxValue = $autoCompleteTextBox.val();
   $dropDown.val(textBoxValue).attr("selected", "selected");
});

And finally I validate the value in the text box is the selected value in the drop down list when the submit button is clicked.

$("#SubmitButton").click(function(e) {
   var textBoxValue = $autoCompleteTextBox.val();
   var selectedValue = $dropDown.find("option:selected").text();
   if (textBoxValue != selectedValue)
   {
      alert(textBoxValue + " is an invalid selection");
      e.preventDefault();
   }
});

I am still pretty amazed by how simple and succinct jQuery is. It was actually really fun to learn and play around with and I look forward to using jQuery in the future.

 | Posted by admin | Categories: Uncategorized |