Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Confused about Single Responsibility Principle in the following example

In the following video, the author takes an existing class and assigns the Single Responsibility Principle to it. He takes a Print Class that has the job of Accessing Data, Formatting, and Printing the report. He breaks up each method to its own class, so he creates a DataAccess class to handle data access, he creates a ReportFormatter class to handle the formatting of the Report, and he creates a ReportPrinter class to handle the printing of the Report. The original Report class is then left with one method, Print() which calls the ReportPrinter's class method Print. DataAccess and ReportFormatter appear to have responsibility, but ReportPrinter relies on DataAcess and ReportFormatter, so doesn't this break the SRP or am I misunderstanding it?

like image 764
Xaisoft Avatar asked Aug 01 '09 00:08

Xaisoft


2 Answers

The Single Responsibility Principle indicates that a given class should have a single responsibility (or 'reason to change'). It does not, in and of itself, indicate how that responsibility is to be satisfied. Doing so can, and often does, require the cooperation of multiple other classes as collaborators.

like image 178
Brandon E Taylor Avatar answered Sep 25 '22 00:09

Brandon E Taylor


Without watching the video, it sounds like a reasonable design. SRP is not broken, as methods dealing with data access do not appear in the ReportPrinter class, only the concept that "I can call something to get the data I want."

You could push it a bit further, and have a coordinator class responsible only for coordinating the activities of the data access class, the formatter class, and the printer class. You could also arrange the objects in different ways, like having the coordinator sends data to the formatter, which sends it to the printer, and the coordinator doesn't (directly) know about the printer.

Something has to know about coordinating the efforts of the narrowly-focused objects. That becomes their responsibility. It's okay to know about the idea or concept of what the other objects will do, so long as you don't know or care how they do it. Thinking of interfaces as "seams of responsibility" is a good start.

It can also be helpful if you think of objects as passing data to each other, rather than "doing" things. So the ReportFormatter returns (or forwards) a new object representing a formatted report, rather than (conceptually) performing objects on an existing report.

like image 34
kyoryu Avatar answered Sep 26 '22 00:09

kyoryu