2014-11-24 36 views
1

我最近一直在想,从设计的角度来看,Log()和Log(LogLevel)之间有什么真正的区别吗?从设计的角度来看,Log()和Log(LogLevel)之间有什么区别吗?

例如,在log4net中,ILog接口的设计如下。

// Design A 
public interface ILog 
{ 
    /* Log a message object */ 
    void Debug(object message); 
    void Info(object message); 
    void Warn(object message); 
    void Error(object message); 
    void Fatal(object message); 

    // ... ignore more members 
} 

但我认为它相当于这样设计的。

// Design B 
public enum LogLevel 
{ 
    Debug, 
    Info, 
    Warn, 
    Error, 
    Fatal 
} 

public interface ILog 
{ 
    /* Log a message object */ 
    void Log(LogLevel level, object message); 

    // ... ignore more members 
} 

那么为什么log4net的不使用设计乙级?任何特定的原因?

我能想到的一个原因是设计A减少了调用者的代码噪声,以便每次指定类似LogLevel.Info的内容。

但是设计B也有一个好处,我们可以在一次调用中改变消息的严重性。例如logger.Log(some_bool_condition?LogLevel.Warning:LogLevel.Error)。但是,当然,我们可以创建一个类似于设计A的包装。

回答

1

从技术上讲,这两种方法都可以从ILog访问,因为它源自ILoggerWrapper。从那里,你可以得到一个ILogger,可以让你直接调用的方法为你所描述的方法B:

void Log(Type callerStackBoundaryDeclaringType, Level level, object message, Exception exception); 
void Log(LoggingEvent logEvent); 

所以具有ILog主要是降低了代码噪音,只是调用如预期幕后记录:

// log4net.Core.LogImpl 
public virtual void Info(object message) 
{ 
    this.Logger.Log(LogImpl.ThisDeclaringType, this.m_levelInfo, message, null); 
} 

显然是有一定空间不同的解释在这里,但这里就是为什么我认为这是最好有调试/信息/警告/错误/致命方法,而不是一个普通的日志(水平)一个。通过强制你的代码使用一种方法,库在编写时强制它声明信息在你的应用程序范围内有多重要。

如果您只能将级别推迟到某个更高级别,那么您只会说“哦,让调用者决定他们想从我的组件中听到多少”。但他们无法知道某件事对你的组件是否重要。你的代码决定了需要什么信息;它的应用程序用户不想听到它,让他通过配置沉默你的记录器,但只有你的代码知道缺席的SQL服务器是否是引起警报或只是一些小麻烦(从最近的开发,在数据库服务器可以消失没有问题,我的组件只要它曾经回答过一次)。

+0

谢谢@samy!通过调用者,我指的是如你所说的调用日志功能的组件。所以从组件的角度来看,有没有真正的区别?我觉得组件调用logger.Error(“something”)等同于logger.Log(LogLevel.Error,“something”),对吧? – Quaker 2014-11-25 06:54:12

+0

这就是代码中发生的事情,但正如我在第二部分所说的那样,当您调用Log.Error(...)时会做出有意识的决定;你说“这很重要”。 – samy 2014-11-25 07:46:31

+0

我明白了。谢谢@samy! – Quaker 2014-11-26 05:11:31

相关问题