SOLID Part 1March 02, 2012 -
The Single Responsibiliy Principle
Robert C. Martin wrote about the principle in his article back in 2002. The principle states:
"There should never be more than one reason for a class to change." — Robert C. Martin
As requirements for your project change, your code will need to change to meet them. The more reasons you have to change a given class, the greater chance you have of introducing bugs. Consider the case of the often misused Application Delegate. According to Apple’s documentation, an Application Delegate’s one responsibility is to respond to application-level events such as your application being sent to the background or your application has finished launching. You might feel tempted to add additional responsibilities to your Application Delegate for convenience. Handling your Core Data stack, downloading content to display in the Application, and other such responsbilities taint the one single job of the Application Delegate. A few problems arise when this happens:
- Changes in the Application Delegate’s other responsibilities require changes to the same class responsible for responding to application events. This potentially results in breaks in your class’s original responsibility: responding to application-level events.
- Multiple responsibilities also reduce your ability to reuse code across your application and/or other projects. Should a command-line utility that wants to use your app’s same storage mechanism require your Application Delegate (and any other classes the Application Delegate needs to do that new job) to do it’s work? Hopefully not, because you don’t get UIKit when you leave the iPhone. This could be painful.
- The extra responsibilities also lead to increased compile time. When you change one class, Xcode needs to re-compile every class that depends on this class. More responsibilities means more classes depending on your class which means more twiddling your thumbs while your computer struggles. This becomes more noticable the larger your application gets.
Apple’s own code follows this rule fairly closely. UITableView, for example, is responsible for handling a collection of cells in a vertically scrolling list. It is not responsible for actually drawing each cell, it leaves this job to cell objects that you supply to the table. It doesn’t keep up with the data that is reflected in the list, it leaves that job to the the object who’s job is to be the datasource (which you provide). Because the table view is only responsible for one job, you don’t need to manipulate or generally even subclass UITableView. To change how information is displayed in the list, simply supply a different UITableViewCell. Want to change how your app knows how many rows to show in your table? Simply supply a different datasource (or change your existing one if necessary). Keeping to one responsibility makes UITableView useful in about a bajillion applications that display all kinds of different lists. Generally it doesn’t hurt to mimic Apple’s own code structure, lots of super smart people have, currently do, and will work there.