Following SOLID first principle, the Class should be responsible for only a single part of the functionality provided by the software.

The same, I guess, goes with the Methods design principle. They should handle only a single "thing".

Let me give an example:

Suppose I have some program in which, at the end of some method, I have three lines in which I open a file, writes a string to it and close the file.

Should I extract a method out of these three lines. Or maybe extract a class which handles this file operation?

What is the rule of thumb?


closed as too broad by Telastyn, Doc Brown, Ben Cottrell, gnat, Arseni Mourzenko May 27 '18 at 19:48

Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer. Avoid asking multiple distinct questions at once. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • 1
    Recommended reading: 8thlight.com/blog/uncle-bob/2014/05/08/… – Ben Cottrell May 27 '18 at 14:54
  • You should think of the one thing/responsibility on a higher, more functional lever than you currently are. It should be a problem domain thing, not a technical implementation detail thing. – Martin Maat May 27 '18 at 20:35

With this limited knowledge of your program, right now my advice is to leave those 3 lines alone.

The issue is you're describing the problem structurally. Some program... End of some method... three lines... There's no story here. No context for this idea to live in.

You're trying to fit an idea into your structured frame of thinking about code and it's flat out breaking it. The concept of "doing one thing" makes no sense when you can literally stuff the entire program into one thing.

This rule isn't about structure. It's about ideas. You could insist that an aardvark riding a bicycle is one thing, but it's a damn weird thing. An aardvark on it's own and a bicycle on it's own are less weird so I'm against the AardvarkBicycle class.

If that seems unsatisfying because it's subjective I say too bad. We're designing software that humans can understand so get used to dealing with our weird human bias.

In his latest book Clean Architecture Uncle Bob redefines the Single Responsibility Principle, when applied specifically to classes, in the context of who the code is responsible to. No class can serve two masters. This is a fine consideration but you're insane if it's your only one. In this view, theoretically, it'd be fine to identify all your stakeholders and give them each their own class and stop decomposing right there. Bleh. That is not what Uncle Bob is saying.

If you insist on thinking structurally the best reason to pick a class over a function is because there is some persisting data that you want to use to change your behavior. Some data that you learn at a different time then when you exhibit your behavior. Now if you only have one behavior a closure might be good enough, if your language has that. If you have two behaviors that need to vary based on this same data you are firmly in object land. Objects are bags of functions that change their behavior together

If you'll join me in also thinking semantically, not just structurally, you'll find it makes sense to extract something as a class if you can think of a good noun that ensures when someone looks inside and sees the details they find pretty much what they expected. If you surprise them you've failed. For functions it's the same story, just with a verb. In either case the fancy term for this is abstraction.

And don't think I didn't notice you using nouns as verbs in the question title :P

If you still feel like you must extract this code I recommend reading up on the hole in the middle pattern

  • Essentially, in the Single Responsibility Principle "responsibility" means "reason to change". In your example, if the class has to change if either the way to write to a file or the format data is output changes, then you should split the class. In this case you may abstract the persistence media to a "PersistenceMedia" interface, and then implement it in a "FilePersistenceMedia" class, responsible of opening, reading, writing, and closing the file. – Jesus Alonso Abad May 27 '18 at 21:45
  • @JesusAlonsoAbad I still want to know more about the context. There are many other considerations. If I left it at that then the single reason to change can be "cause Abe in accounting said so". I'd like to decompose down smaller than AbesAccounting class. These ideas are good but they are not compatible with structure only thinking. – candied_orange May 27 '18 at 21:52

Not the answer you're looking for? Browse other questions tagged or ask your own question.