Should registration be performed inside a class whose main purpose is not registered?

This is rather a theoretical question. Should registration be performed inside a class whose main purpose is not registered?

Here is a simple interface for everything that will prepare the calculation for the number.

public interface ICalculation { 
    public int calculate(int number); 
}

Here is the implementation of the ICalculation interface, which performs the calculations and performs some logging. I think this is a very pragmatic approach. Aside from a constructor that accepts what we usually don't expect to see computations in a domain, built-in logging may not be intrusive.

public class ReallyIntenseCalculation : ICalculation {
    private readonly ILogger log;

    public ReallyIntenseCalculation() : this(new DefaultLogger()) {
    }

    public ReallyIntenseCalculation(ILogger log) {
        this.log = log;
        log.Debug("Instantiated a ReallyIntenseCalculation.");
    }

    public int calculate(int number) {
        log.Debug("Some debug logging.")
        var answer = DoTheDirtyWork(number);
        log.Info(number + " resulted in " + answer);
        return answer;
    }

    private int DoTheDirtyWork(int number) {
        // crazy math happens here
        log.Debug("A little bit of granular logging sprinkled in here.");
    }
}

After removing all the logging code from ReallyIntenseCalculation, the code now has a clear unified responsibility .

public class ReallyIntenseCalculation : ICalculation {

    public int calculate(int number) {
        return DoTheDirtyWork(number);
    }

    private int DoTheDirtyWork(int number) {
        // crazy math happens here
    }
}

, ReallyIntenseCalculation . . .

, ICalculation, , , ReallyIntenseCalculation.

public class CalculationLoggingDecorator : ICalculation {
    private readonly ICalculation calculation;
    private readonly ILogger log;

    public CalculationLoggingDecorator(ICalculation calculation, ILogger log) {
        this.calculation = calculation;
        this.log = log;
        log.Debug("Instantiated a CalculationLoggingDecorator using " + calculation.ToString());
    }

    public int calculate(int number) {
        log.Debug("Some debug logging.")
        var answer = calculation.calculate(number);
        log.Info(number + " resulted in " + answer);
    }
}

?

+3
3

, . , .

, , , - - . , . AOP, #.

- , , , .

+3

, .

, , . , unit test , , .

AOP - , .NET PostSharp .

AOP , DI, , , , , , , , , .

public class ReallyIntenseCalculation : ICalculation {

    public int calculate(int number) {
        return DoTheDirtyWork(number);
    }

    private int DoTheDirtyWork(int number) {
        // crazy math happens here
    }
}

public class CalculationLoggingDecorator : ICalculation {
    ICalculation calculation;
    ILogger log;
    public CalculationLogging() {
        this.calculation = new ReallyIntenseCalculation() ;
        this.log = SomeLogger(...);
        log.Debug("Initialized a CalculationLoggingDecorator using " + calculation.ToString());
    }

    public int calculate(int number) {
        log.Debug("Some debug logging.")
        var answer = calculation.calculate(number);
        log.Info(number + " resulted in " + answer);
    }
}

, - , , , , , ReallyIntenseCalculation , .

, AOP , DI .

: .

, , , .

AOP , - , DI.

, - , DI, app.config, , . , , , , .

+3

How many registrars do you have? I would make the implementation of the calculator constructor a private instance of the log instance using the Singleger Logger or Logger factory method (so logging or not logging is not part of the public calculator API, but is part of the calculator implementation).

0
source

Source: https://habr.com/ru/post/1723919/


All Articles