【问题标题】:Design Pattern to make logging available without breaking abstractions在不破坏抽象的情况下使日志记录可用的设计模式
【发布时间】:2020-11-20 17:36:32
【问题描述】:

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

所以,有一个TestCase 类。这个类是我编写的所有测试用例的基础,我开发的任何测试用例都必须继承自它。测试用例有记录方法,如LogInfoLogConfirmation等。

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

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

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

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

有什么方法可以让SignalGroup 可以使用更松散的耦合进行日志记录,因此它不需要直接了解TestCase 类?

【问题讨论】:

  • 您的TestCase 类结构与您向我们展示的Set 方法之间的联系是什么?这个问题没有说清楚。例如,为什么不能在 int value 传递到 Set 之前记录它,因为值没有被修改?你的TestCases 没有提供这个值吗?

标签: c# design-patterns abstraction


【解决方案1】:

作为一个跨领域关注点,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 来装饰“真实的”SignalGroup 类,例如new LoggingSignalGroup(logger, new SignalGroup())...

如果您无法定义像ISignalGroup 这样的接口,则可以改为定义以这种方式工作的Adapters

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-26
    • 2020-11-11
    • 2019-08-25
    • 2016-12-17
    • 1970-01-01
    • 2019-06-27
    相关资源
    最近更新 更多