在不破坏抽象的情况下使日志可用的设计模式

Design Pattern to make logging available without breaking abstractions

目前,我在一个由我所在公司的其他人开发的框架内工作,因此我在架构方面有一些限制。我希望有一种设计模式或某种方式可以用现在设置的方式处理我的日志记录,而不会破坏抽象。

所以,有一个TestCaseclass。这个class是我写的所有测试用例的基础,我开发的任何测试用例都必须继承它。测试用例有记录方式,如LogInfoLogConfirmation

现在我有另一个名为 SignalGroup 的 class,其中包含一个或多个信号。 SignalGroup 有一个 Set 方法,它抽象了一个或多个值设置背后的逻辑。它通过了解系统处于哪种模式等来实现这一点。因此,例如,保持简单,SignalGroup 的设置方法可能只是以下一种模式,它将导致设置一个组中的所有信号到一个值:

public void Set(int value){
   foreach (Signal signal in Signals){
    signal.Set(value)
   }
}

现在,在该设置方法中,我需要使用 TestCase 基础 class 中的 LogInfo 方法记录每个信号设置的值。我的问题是,现在我要么需要

  1. 让我的 SignalSignalGroup 知道 TestCase 基数,这样它就可以保持围绕设置值的抽象,但也可以调用 LogInfo 方法
  2. 让我的测试用例库了解 SignalGroup 中的信号,以便我可以在其层实现日志记录。但这意味着我必须让 TestCase 包含关于我真正想抽象掉的各个信号的逻辑。

有什么方法可以让 SignalGroup 可以使用稍微松散耦合的日志记录,这样它就不需要直接了解 TestCase class?

作为交叉关注点,logging should be implemented using the Decorator design pattern

使 Set 方法成为虚拟方法,最好将其定义为接口方法,例如

public interface ISignalGroup
{
    void Set(int value);
}

然后像这样实现一个LoggingSignalGroup

public class LoggingSignalGroup : ISignalGroup
{
    public LoggingSignalGroup(TestCase logger, ISignalGroup inner)
    {
        Logger = logger;
        Inner = inner;
    }

    public TestCase Logger { get; }
    public ISignalGroup Inner { get; }

    public void Set(int value)
    {
        Logger.LogInfo(value);
        Inner.Set(value);
    }
}

使用LoggingSignalGroup修饰'real'SignalGroupclass,例如new LoggingSignalGroup(logger, new SignalGroup())...

如果您不能定义像 ISignalGroup 这样的接口,您可以改为定义 Adapters 以这种方式工作。