Single Responsibility Principle : class level or method level [closed]
Asked Answered
L

3

10

I have problem in understanding Single Responsibility Principle. Should SRP be applied at class level or at method level? Lets say I have a Student class, I need to create student, update student and delete student. If I create a service class that has methods for these three actions does this break the SRP principle?

Lozenge answered 28/11, 2015 at 7:45 Comment(2)
Here's a simple heuristic... If you can't describe the thing's job (whether a method, class or even module) without using the word "and" then you need to break it up. Your service class "manages student objects" and so satisfies SRP. :-)Hieronymus
The SRP applies only at the class level. At the method level is a different principle: What is the scope of the Single Responsibility Principle?Prosit
L
4

I'd say you have a service class which is responsible for CRUD operations on objects of type Student. I don't see this design to violate SRP at all.
Quoting from http://www.developerfusion.com/article/137636/taking-the-single-responsibility-principle-seriously/

Two methods of the same class (or even different classes) should focus on different aspects. However, two methods in the same class, e.g. a repository, likely will both have to be concerned with the same higher level responsibility, e.g. persistence.

I see CRUD as well-known operations within a single context unless you have some business associated with it. For example you might want to allow some classes to only be able to read data and deny them from making any changes to it. That's when you can make use of another SOLID principle Interface segregation.
You can define an interface with only read method defined to be used in those classes. Or if it makes sense (performance-wise for example), create a separate concrete class that just implements read operation.

Leclair answered 28/11, 2015 at 7:58 Comment(2)
My confusion is definition of Single Responsibility is huge , if i have batch process where i have to process the data is actually a Single responsibility and this Responsibility includes reading,processing and writing . So should my class do all three or should i have three different classes for each of theseLozenge
It is open I agree. One could interpret both outcomes from the general definition of SRP. And this not an uncommon debate in patterns and practices. It really depends on how you categorize and abstract requirements. For example To me, a method should not be responsible for both adding and updating. But these methods could reside in the same class which is responsible for persisting student data. In my point of view, Having separate classes for CRUD operations is just over-using the principle unless you have to (see my example in the answer). So I wouldn't do it if I don't have to.Leclair
I
4

SRP is at both at class and method level.So if you ar talking about student class then only responsibility it has in this case to do CRUD on student entity.At the same time when you talk about methods the you should not have an InsertStudent method and do both Update and Insert in it based on ID .That breaks SRP.But if you have InsertStudent which inserts and UpdateStudent which updates it follows SRP

Instate answered 28/11, 2015 at 7:59 Comment(0)
R
2

Not to criticize because I believe in the principle, but don't follow the advice that says it fits if you can summarize the functionality without using "and". With this kind of logic you could still have an enormous one file application and say its responsibility without using "and". A web browser is a complicated piece of software but you can still describe it in one short statement. And it makes total sense because the thing is like a pyramid and you should always be able to describe the top level regardless of the parts being split or not.

That is precisely what we do everyday with functions. You pick a very simple function name which hides the complexity like "connect" for a socket. You actually don't know from this point of view if it is split afterwards. It could be a giant function.

I am afraid it is still subjective. You don't want to judge your design based on your ability to summarize a functionality with words. You always should be because this is how you pick method names and we all know naming is hard.

My advice is to see the SOLID principals as a whole instead of individual rules and build separation around what you think is going to change, and what is less likely to change. The obvious candidate being dependency. It is still going to be subjective, there is no way around that, but it'll help you.

I personally find it very difficult to do at times, but it is worth it. I don't know if you know Ecto which is an elixir project, but I had a "Voilà" moment when I've discovered it. It is not perfect is many ways, but the thing with Ecto and separation of concerns in general is that it seems a lot of indirections at first, but then the things are separated make sense. In its best blissful moments, it feels like a lot of small parts that you can trust.

I used to be in the position where it made sense to me that a model should be so smart that it knows how to save itself to the database, how to validate itself, how to do all sorts of things. But the reality is that as soon as you decide you want to work with another database, or validate differently depending on cases, etc, then it becomes hard to get your way out of this. I am sure some developer may have never felt this way and that is fine. But for me it is a challenge.

Lots of simple cases, but you want each class to know as less as possible. You don't want your Mail class to know that the css colour for "urgent" is "#FF0000". And then harder ones like sometimes you don't even want it to know it is "urgent" because it depends on use case facts.

This is not easy. In your specific case, I personally would not bother mixing "create" and "delete" for example, but I would make sure interacting with the database is all it does. It does not know if the thing is valid, if it has callbacks, etc. Pretty much the Repository pattern. Again Ecto is a good example, or at least I find it helpful.

Rhinoscopy answered 7/10, 2019 at 5:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.