SRP: Single Responsibility Principle

August 20th, 2006 3 comments

SRP is one of the fundamental object oriented software design principles, first introduced by Tom DeMarco in 1979.

In simple terms, SRP states that every class should have a single well defined goal, and that all members of that class (properties, methods, etc.) should work together to achieve that goal. Robert Martin puts it in slightly different terms:

There should never be more than one reason for a class to change.

Essentially SRP enforces the concept of high cohesion that should not only be applied to classes but also internals of a class, such as methods.

So why is SRP such an important design principle? It is because a class with multiple responsibilities is more difficult to change and more difficult to reuse (design smells: fragility and immobility).

While SRP is quite easy to understand, it’s not always logical to implement. Consider the following class:

Given the convenience of having a customer class that is smart enough to know how to load and save itself, would you rather break it out like this?:

According to SRP, you should, because the combined customer class shares multiple responsibilities: customer business logic, and customer persistence logic. In fact if you use TDD, you may even be forced to separate these two responsibilities.

In practicality, however, while we should keep this principle in mind and try to apply it wherever it makes sense, we should never get so carried away that we start introducing other design smells in our architecture, such as Rigidity, Viscosity, and Needless Complexity.

Generic Collection and ReadOnlyCollection Are Actually Not Misplaced

August 19th, 2006 Comments

Since I started using generic collections in .NET Framework 2.0, it always bothered me that Collection<T> and ReadOnlyCollection<T> objects reside in the System.Collections.ObjectModel namespace rather than where they actually belong in the System.Collections.Generic namespace. Today I came across this blog by Krzysztof Cwalina that explains why Microsoft made this decission. Now it makes good sense to me.

Inherit With Care

July 18th, 2006 Comments

I was asked to look at an ASP.NET 1.1 application that was designed with a distributed architecture using .NET Remoting. Over a period of a few hours of heavy usage, this production application would intermittently bring the Windows 2003 Server that it was being hosted on to a screeching halt. Cause unknown. No event log entries, nothing suspicious in IIS logs, nothing too special about the application that would indicate this behavior. Performance monitoring, however, indicated that the handles on the OS would gradually increase to dangerous levels of 50,000+ before the application would crash. Hmmm, what could be using so many handles and not releasing them? My first instinct was to make sure that all the remoting objects were disposed properly after use. Upon closer investigation, however, I found out that all ASP.NET pages in the application were inheriting from a custom base class. The base class was overriding the page’s Init method, and guess what I found in that method? A call to RemotingConfiguration.Configure() method. At first I was surprised why would someone configure remoting every single time a page is instantiated? Soon it hit me why system handles were astronomically increasing. Once that line of code was moved to Application_Start event, the application hasn’t crashed in weeks. Moral of the story? Inheritance is a good OO concept, but only we as developers can decide how badly we want to abuse it!

Which UML Models Are The Most Important?

July 17th, 2006 Comments

Well, the answer depends on who you ask and what they are trying to model, but the following five models have proven to be essential to me on almost every project since I started using UML:

  1. Activity
  2. Use Case
  3. Class
  4. Component
  5. Deployment

Class models are obviously the most important ones since I can directly generate code from them. Others help me generate artifacts that I feel are essential for project documentation.