0

Consider following class:

public class Foo 
{
    public Foo() {}

    public void Bar(int input)
    {
        Console.WriteLine("Working on input ...");

        switch(input)
        {
            case 1:             
                File.WriteAllText("PATH", "The input is 1");
                break;

            case 2:             
                var data = int.parse(DateTime.Now.ToString("yyyy")) + input;

                File.WriteAllText("PATH", data);
                break;

            ...
        }
    }
}

This is a simple class, still have more than 1 responsibility, I think there is 2 responsibilities:

  • Logging Console.WriteLine
  • Persistence File.WriteAllText

Maybe there is more than this 2

Is there any guideline in order to helping us detect class responsibilities, so we can refactor it and for example apply SRP?

Mehdi Dehghani
  • 296
  • 2
  • 11
  • Hmm, I have some doubts that _Logging_ from within a class really violates the SRP. It's just a feature for diagnosing what's going on, and might be used in any situation. – πάντα ῥεῖ Dec 22 '19 at 14:35
  • @πάνταῥεῖ If logging violates the SRP, then after a programmer creates a BarLogging class with the single responsibility of logging for the Bar function, using that BarLogging class to do the logging is again violating the SRP, so OP should better write a BarLoggingCaller class whose single responsibility it is to call the BarLogging class. Except that calling the BarLoggingCaller class is again a SRP violation, right? – gnasher729 Dec 22 '19 at 15:10
  • @gnasher729 It's a fallacy of what SRP really means. I do support your answer a 100%. – πάντα ῥεῖ Dec 22 '19 at 15:14
  • @πάνταῥεῖ I think the logging violates the SRP, because if we decide to change the logging to something else than _Console.WriteLine_, we need to open this class and modify it. am I right? – Mehdi Dehghani Dec 22 '19 at 16:40
  • @gnasher729 _using that BarLogging class to do the logging is again violating the SRP_, why? – Mehdi Dehghani Dec 22 '19 at 16:41
  • @MehdiDehghani Well, you might inject an interface to do the actual logging into your class. – πάντα ῥεῖ Dec 22 '19 at 18:05
  • @MehdiDehghani: The argument is "logging is a second responsibility, therefore SRP violation". If you replace logging with a specific logger function, calling that is an SRP violation by the same argument. An caling a logger function caller is an SRP violation. Reductio ad absurdum. The whole argument that it is an SRP is nonsense. – gnasher729 Dec 22 '19 at 19:03
  • @MehdiDehghani Wrong. If you decide to change how to do logging, you are still logging. You can change implementations. – gnasher729 Dec 22 '19 at 19:07
  • @gnasher729 I have to log in Foo class, I can put the whole log logic inside Foo class, or create separate class and even use DI to inject that class to Foo. are you saying both way violate the SRP? I didn't get this part. – Mehdi Dehghani Dec 23 '19 at 05:21

1 Answers1

4

Stop right there. You are falling into the trap - misinterpreting what "single responsibility" means.

Take a driving instructor whose single responsibility it is to teach people how to drive a car. He teaches the students hundred different things they need to know to drive. He also drives around to pick students up for their lessons or drop them off afterwards, does paperwork so that bills can be sent, makes sure the care is in a safe condition and so on. It's all part of the single responsibility.

Single responsibility does not equal "one single action".

gnasher729
  • 42,090
  • 4
  • 59
  • 119
  • 3
    Right, and just because those things could be given to other people to do doesn't stop it from being a single responsibility either. SRP says one class, one responsibility. It doesn't say one responsibility, one class. That's not the same thing. – candied_orange Dec 22 '19 at 15:09
  • Sure, _Single responsibility does not equal "one single action"._ but I think those actions should be related, for example in `Foo` class, the logging is separate things, also dealing with file and IO. so the _single action_ here means related action(s). – Mehdi Dehghani Dec 22 '19 at 16:44
  • @MehdiDehghani it's how you decide what is related that you're missing here. The line between responsibilities is not decomposition. It's change. Another way to say it is "gather together those things that change for the same reason, and separate those things that change for different reasons.". Until there is a reason Foo logging and Foo persistence would be forced to change independently SRP does not mandate that they be seperated. – candied_orange Dec 22 '19 at 18:27
  • 1
    "Persistence" and "logging" are not responsibility. If you want to talk about responsibility, you need to write down some concrete responsibility. You can't argue about these things in a meaningful way with toy example. But in this case, it seems evident that the logging would log the fact that the code does some part of the responsibility of the class, so if that responsibility changes, then the logging would change. – gnasher729 Dec 22 '19 at 18:59