设计具有多个实现的静态Logger

时间:2017-03-23 11:15:38

标签: c# logging design-patterns

目前,有一种API类型方法可以跟踪其他相关应用程序的日志

public class Logger {
    public static void Init() {}
    public static void Verbose(string msg) {}
    public static void Warn(string msg) {}
    public static void Error(string msg) {}
}

通过一些设计更改,我想介绍另一种类型的Logger,将根据某些条件激活

protected class FileLogger {
    public static void Verbose(string msg) {}
    public static void Warn(string msg) {}
    public static void Error(string msg) {}
}

protected class ConsoleLogger {
    public static void Verbose(string msg) { //do diff}
    public static void Warn(string msg) { // do different}
    public static void Error(string msg) {}
}

Logger已经公开,可以静态方式Logger.Warn("test")调用。在不违反合同的情况下隐藏实施的理想设计模式/实现是什么。

一种简单的方法是在主if and else中使用Logger来推送应该调用哪一个看起来很模糊。

由于它的Logger没有公开interfacewith static方法,所以right design to solve the problem?

是什么

3 个答案:

答案 0 :(得分:1)

可能你可以使用某种功能方法

例如:

public static class Logger
{
     public static Action<string> Verbose { get; set; }
     public static Action<string> Warn { get; set; }
     public static Action<string> Error { get; set; }
}

在应用程序初始化期间,您可以将默认委托设置为这些属性,并且合同不会被破坏,因为整个Logger操作将作为常规方法调用:

public void Main()
{
    Logger.Verbose = message => 
    {
        // Do stuff here: log text to a file
    };

    Logger.Warn = message => 
    {
        // Do stuff here: log text to a file
    };

    Logger.Error = message => 
    {
        // Do stuff here: log text to a file
    };
}

也就是说,您不需要将实现作为类,而将实现作为代理。您可以为代理人提供登录文件,某些云服务或仅控制台输出...

我猜你会遇到一些遗留代码,这就是需要这样的解决方法的原因。

  

通过一些设计更改,我想介绍另一种类型的Logger,将根据某些条件激活

根据我的建议,您应该可以通过将代理存储在某处来替换Action<string>实现,以便将其设置为Logger

Logger.Verbose = FileLogger.Verbose;
BTW我认为坚持使用静态方法是一个坏主意......如果一个线程需要一个日志实现而另一个需要其他的呢?你会得到一些奇怪的解决方案......

答案 1 :(得分:1)

如果必须使用静态解决方案,则可以简单地创建调用非静态类型的静态方法适配器,然后在Init方法中注入实现:

public static class Logger {

    public interface ILog { 
        void Verbose(string msg);
        void Warn(string msg);
        void Error(string msg);
    }

    private static ILog Log {get; set;}

    public static void Init(ILog log) { Log = log; }
    public static void Verbose(string msg) { Log.Verbose(msg); }
    public static void Warn(string msg) { Log.Warn(msg); }
    public static void Error(string msg) { Log.Error(msg); }
}

如果你想逐渐从静态迁移,这也可以很容易地将ILog的实现直接注入到新代码中。

答案 2 :(得分:0)

可能的解决方案是使用Observer
Logger是Subject,FileLogger / ConsoleLogger是Observers。

记录器的类型&#34;将根据特定条件激活&#34;(将观察者附加/分离到主体)。