Search code examples
c#oopsolid-principlessingle-responsibility-principle

Single Responsibility Principle Violating


I have a class with two methods. While app running I send instance of Operations to another class as a parameter.

  public class Operations
{
    /// <summary>
    /// calculating the available money to use in operations
    /// </summary>
    void CalculateAvailableAmount(int x)
    {
        //making some calculation
    }

    /// <summary>
    /// sharing some values between shareholders
    /// </summary>
    void Distribute(decimal total)
    {
        //making some calculation
    }
}

after I wrote above, realized I should use interface, because logic of methods can be changed(I use interface as a parameter).

public interface IOperations
{
    void CalculateAvailableAmount(int x);
    void Distribute(decimal total);
}

But I cannot decide that, these two methods not directly depends each other however, both of them making calculating some values and distribute these values. Here I thought that 2 methods' logic can be changed after a while. Also probably I will write more than 10 methods like above, Is that violating SRP ? Keeping related methods seems better idea in a class but other hand I though that it can violate SRP principle. Which one is better to implement ? all methods in different classes and different Interfaces, or is that ok ?

thank you


Solution

  • It sounds like what you are concerned about is not really the SRP, but more about how to organize code. It looks like you are organizing like methods together, which is a fine way of code organization. If CalculateAvailableAmount and Distribute are logically or functionally connected, then it looks to me. Yes, the OOP paradigm often calls for organizing methods based on what data that they operate on, but organizing by logic or function is valid as well (though it might not be OOP).

    The Single Responsibility Principle is a very nebulous, philosophical principle. Many people struggle with deciding on how granular or coarse a single method/class/module should be. The following is just by own thoughts on it, and it is by no means an exact definition, because no exact definition exists.

    I think the general rule of thumb is to separate out code into it's own module if that code has a high chance of changing independently of the surrounding code. This can mean a method or group of methods in a class, or a block of code within a method, or even splitting up a library.

    I think there are generally two different angles you can take when applying the SRP.

    There is the YAGNI/DTSTTCPW angle, where you don't apply the SRP until it makes sense to, or until you are 100% it would help you in the future. Taking your example, you run with keeping those two methods in that same class until you realize that one or more of them are changing implementations quite often compared to the surrounding code. At that time, it might make sense to separate them out by applying the SRP...or it might not. Maybe keeping the code in one place is more beneficial then fragmenting it off into another file with the SRP. Or maybe you should apply the SRP if multiple developers are going to be working in the same module. It might make sense to SRP that module so you don't step on each other's toes...But maybe that is more of separation of concerns as opposed to the SRP

    Or you can come from the up-front design angle, and guess which blocks of code will be frequently changed relative to the surrounding code, and prematurely apply the SRP to your code base. I have a biased against this approach (especially on in-house only code) because I think it tends to fragment code, and I personally find fragmented code harder to maintain. Others find that small bits of code are easier to understand and maintain.

    Anyways, I hope that helps a little. Don't get too hung up on it. SOLID and design patterns are meant to solve problems. If you don't have a problem, then keep on keeping it simple. And if you end up having a problem, then that is what refactoring is for :)