Locked learning resources

Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Locked learning resources

This lesson is for members only. Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Single Responsibility

00:00 In the previous lesson, I talked about whether to use an object-oriented approach in Python. This lesson kicks off the SOLID principles.

00:09 The S in SOLID is the single-responsibility principle. It is stated as a class should have only one reason to change Let’s break that down. What a class does is expressed through the methods.

00:23 It provides its responsibility. If your class implements more than one task, you’re breaking the single-responsibility principle, and you should break your class up into multiple classes.

00:35 This is all about the separation of concerns. Let’s look at an example in code.

00:44 Consider this class that abstracts a file. Its interface includes a method for reading a file, a method for writing a file, one for compressing a file to ZIP format, and one for decompressing from ZIP format.

01:01 Does this seem like a single responsibility? Yeah, not really. Not all the file objects you create are going to need compressing and uncompressing. Only ZIP files do.

01:12 That’s a sign that you’re doing too many things in the class. The solution is to break this up into more pieces.

01:23 Instead of having a single file manager, this module implements the same functionality as two different classes. The FileManager class abstracts the reading and writing of the class having the read and write methods from before, while the ZipFileManager contains the compress and decompress methods.

01:44 I haven’t done it here, but you could imagine a method on ZipFileManager that returns a FileManager object pointing to the uncompressed file that was ready for reading and writing.

01:56 You want to separate out your responsibilities because it means less to keep in your head while you’re maintaining the class. Smaller chunks of code tend to be easier to test and debug.

02:08 This isn’t just because they’re smaller, but because you can separate out expected behavior. For example, if you think back to my bad file manager, what does it mean to read or write to it? If it’s still compressed, does the class implement that, or would it muck things up?

02:25 Single-responsibility doesn’t mean only a single method. You still want all the methods that make sense for the data on the class. Assuming you pick the right data abstraction, the better file manager needs both the read and write methods, but mixing in compress and decompress makes things messy.

02:44 Fundamentally, The File and ZipFile classes have different purposes and do different things. One is for reading and writing a file.

02:52 The other is for compressing and decompressing. That’s not to say you couldn’t come up with a better abstraction. You could could build a version of the Zip class that only implements read and write, decompressing and reading or decompressing and writing, then compressing back when it’s done.

03:07 Uncle Bob’s paper on the topic tells a story where he was writing code for a multipurpose printer. Originally, he just had a Printer class, but maintaining the fax machine and scanning functionality in that class didn’t make a lot of sense. So instead he split it up into three different classes.

03:26 That’s the S. Next up, the O in SOLID.

Become a Member to join the conversation.