Applying the Single Responsibility Principle

I reviewed a bit of code today that presents an excellent opportunity to discuss a big difference between procedural and object-oriented code. Here’s the code I reviewed:
private void DisplayCoBrandedImages()
    string imageUrl = "~/images/cobrand/" + ContractId + ".gif"; 
    bool isCoBranded = File.Exists (Server.MapPath(imageUrl)); 
    bool isGroup = (Page.Category & DisplayCategory.GroupLevel) == 

    if (isGroup)
        imageUrl = "~/images/cobrand/GroupOnlineLogo.gif";

    _brandedImage.Visible = isCoBranded || isGroup; 
    _brandedImage.ImageUrl = imageUrl;
This is a good example of procedural code, where a single method has multiple responsibilities. In this case, the method DisplayCoBrandedImages is:
  • Determining if the page should be co-branded;
  • Determining if the page is a group page;
  • Determining which image to display; and,
  • Setting the properties of the image control.
In object-oriented programming, however, we strive to follow the Single Responsibility Principle, which states that code should only have one reason to change. But, any of the tasks mentioned above might change independently of the other tasks. So, if I were to refactor this code into a more object-oriented structure, I would expect to see a different method (or property) handling each of those items above, like this:
private void DisplayCoBrandedImages()
    _brandedImage.Visisble = IsCoBranded || IsGroup; 
    _brandedImage.ImageUrl = GetImageUrl(); 

private bool IsCoBranded
    get { return File.Exists(ImageUrl); }

private bool IsGroup
    get { return (Page.Category & DisplayCategory.GroupLevel) == 
        Page.Category; }

private string ImageUrl
        if (IsGroup)
            return "~/images/cobrand/GroupOnlineLogo.gif";
            return "~/images/cobrand/" + ContractId + ".gif";
Now, the primary method (DisplayCoBrandedImages) is only responsible for setting the attributes of the image control. It relies on helper methods (or, as in this case, properties) to perform the other, subordinate tasks. The resulting code, while longer, is easier to understand, because each method is only doing one thing.

Coding Standards

I wish I could remember who told me this…

It does not matter which side of the road we drive on, as long as we all drive on the same side as everyone else.

My Marick Test Matrix

I introduced the Marick Test Matrix in the previous post. As much as I like it and have come to rely on it. One thing has always bugged me about the matrix: The terms Brian used to describe his horizontal axis seem, IMHO, obtuse. Instead, I prefer these simpler terms:

  • Support Programming = Define Requirements
  • Critique Product = Identify Defects

Given those changes, here’s my updated matrix:

I prefer these axes because now I can refer to each quadrant by a simple name:

  • Business/Requirements
  • Business/Defects
  • Technology/Requirements
  • Technology/Defects