Search code examples
c#oopdesign-patternsdesign-principles

Is calling into other code a (SOLID) Single Responsibility Principles (SRP) violation?


Considering this class with business logic:

public static class OrderShipper
{
    public static void ShipOrder(Order order) {
        AuthorizationHelper.AuthorizedUser();

        using (new PerformanceProfiler()) {
            OperationRetryHelper.HandleWithRetries(() => ShipOrderInTransaction(order));
        }
    }

    private static void ShipOrderInTransaction(Order order) {
        using (var transaction = new TransactionHelper()) {
            ShipOrderInternal(order);

            transaction.Commit();
        }            
    }

    private static void ShipOrderInternal(order) {
        // lots of business logic
    }
}

The class contains some business logic, and executes some crosscutting concerns as well. Although there is no doubt about that this class violates the Open/Closed Principle, does this class violate the Single Responsibility Principle?

I'm in doubt, since the class itself is not responsible for authorizing the user, for profiling the performance and for handling the transaction.

There is no question about this that this is poor design, since the class is still (statically) depending on those crosscutting concerns, but still: Is it violating the SRP. If so, why is this?


Solution

  • It's a good question, the title is slightly misleading (it's unlikely you can build an application without "calling into other code"). Remember that the SOLID principles are more guidelines than absolute rules that must be followed; if you take SRP to its logical conclusion, you will end up with one method per class. The way to minimise the impact of cross-cutting concerns is to create a facade that is as easy as possible to use. In your examples you have done this well - each crosscutting concern only uses one line.

    Another way to achieve this is through AOP, which is possible in C# by using PostSharp or through IoC interception