Previously I blogged about the 5 SOLID Design Princinples.  Now I will break them down independently starting with Single Responsibility.

Most of the information and examples in this post are from Chapter 2 of Practical Objected Oriented Design in Ruby (aka POODR) by Sandi Metz.  I highly recommend reading this book.

Single Responsibility refers to classes and methods that do the smallest possible useful thing.  Applications that are easy to change consist of classes that are easy to reuse.  Reusable classes are pluggable units of well defined behavior that have few entanglements.  A class that has more than one responsibility is difficult to reuse.

One way to determine if a class has single responsibility is to ask it questions about its methods.  "Please Mr./Mrs. classwhat is/are method?“  Another way is to attempt to describe the class in one sentence.  If the simplest description has the word "and” then the class has more than one responsibility.  If it has “or” then the class has more than one responsibility and they aren’t even very related.

When everything in a class is related to its central purpose, the class is said to be highly cohesive or to have a single responsibility.

  Implementation:

  1. Hide Instance Variables: Always wrap instance variables in accessor methods instead of directly referring to variables.  This changes the instance variable from data referenced all over to behavior which defined only once.
  2. Hide Data Structures:  If the data coming into the class is a complicated data structure (i.e. array of arrays) then separate the structure from meaning.  A handy way to do this is with Structs.  Here is the example they use in POODR.  This style of code allows you to protect against changes in exteranlly owned data structures and to make your code more readable and intention revealing.
  3. Extract extra responsibilities from methods:  Same way as classes; ask them questions about what they do and try to describe their responsibilities in a single sentence.  Guidelines: Separate iteration from the action that’s being performed on each element.  Extract calculations that are not directly related to the single responsibility of the method.
  4. Isolate Extra Responsibilities in Classes:  Here is the refactored example that moves the diameter method into the wheel struct.

Methods that have a single responsibility:

  • Expose previously hidden qualities.
  • Avoid the need for comments.
  • Encourage reuse.
  • Are easy to move to another class.