Join Steven Lott for an in-depth discussion in this video Introduction to single responsibility, part of S.O.L.I.D. Programming Principles.
- View Offline
- The fifth and final solid design principle I'd like to demonstrate is the single responsibility principle. The single responsibility principle says a class should have responsibility over a single part of the functionality provided by the software, and that responsibility should be entirely encapsulated by the class. A common paraphrase of this is a class should have only one reason to change. This raises an interesting question. What does single mean in this context? Does single mean a whole boat or one mast or one sail? What's single? The question is really about finding the right level of abstraction.
The goal is to have a class which can be summarized with a succinct responsibility statement. The statement distinguishes one class from all the other classes in the application. Membership in the class is unambiguous. A class which models a ship as a whole will be a composite object that includes hull and rig. The parts will also have single responsibilities but in a different level of abstraction. What's a responsibility? It can help to take hints from the general responsibility assignment software principles, GRASP.
For more information, read Craig Larman's book, Applying UML and Patterns. GRASP provides a set of concepts that can be used to sort out relationships among classes. There are a number of principles for determining what counts as responsibility. I'll look at just two, controller and creator. A controller class is responsible for all the processing to complete a use case or story. In a Badger command line context a controller could process a whole file of data.
In a graphic user interface context, a controller could implement a button click or a keyboard event. In my examples, I've been making a tacit assumption that there's a simulator of some kind that simulates play and collects data on winning and losing. This would be the controller. Another kind of responsibility is a creator. This is a class or function that is responsible for creating other objects. Many of the examples have included factories to create individual objects and builders to create complex objects.
Interface segregation principles suggests that construction be segregated from ordinary essential operations. The dependency inversion principle suggests classes depend on abstractions, not other concrete classes. Both of these principles suggest that a creator is an important kind of single responsibility. The solid single responsibility principle suggests that classes be focused, but what does single really mean? The hard part is locating an appropriate level of abstraction.
The general responsibility assignment software principles provide a way to identify the single responsibility for a class or module. Controllers and creators are two ways to define a single responsibility.
To incorporate SOLID into your own development workflow, Steven Lott has prepared a series of lessons that break down the principles one by one, with real-world examples. Learn how to use these principles in the design process, and to test the strength of your code along the way. Steven uses Python to demonstrate the concepts, but they're useful for any object-oriented programming language.
- An overview of SOLID principles
- Segregating code into client-specific modules
- Testing code by substituting subtypes for base classes
- Keeping software open for extension but closed to modification
- Eliminating dependencies on details
- Assigning one responsibility to each class
- Using SOLID principles in the design process