我在应用程序中使用log4net进行日志记录。
我想避免讨论实现日志记录外观,但实际上,我正在创建一些允许通过构造函数注入ILog
实现的类。例如:
abstract class MigratorBase<T> : IMigrator<T>
{
private ILog logger;
public MigratorBase(ILog logger)
{
this.logger = logger;
}
}
我还想在类上提供一个默认构造函数,如果调用它,实际上会禁用日志记录(或者记录为空)。而不是散布代码片段来检查记录器是否为空,例如:
if (this.logger != null)
Log.DebugFormat("Connecting to {0}", this.href);
我认为实现此功能的更好方法是分配一个纯粹为空方法的ILog
实现。我可以称之为NullLog
,看起来与此类似:
class NullLog : ILog
{
public void Debug(object message, Exception exception) { }
public void Debug(object message) { }
public void DebugFormat(IFormatProvider provider, string format, params object[] args) { }
...
...
}
然后在默认构造函数中,我可以将这种类型的对象分配给类的私有成员,如下所示:
abstract class MigratorBase<T> : IMigrator<T>
{
private ILog logger;
public MigratorBase(ILog logger)
{
this.logger = logger;
}
public MigratorBase()
{
this.logger = new NullLog();
}
}
这种方法对我来说似乎更面向对象,所以我认为我喜欢它,但谷歌搜索似乎揭示了人们暗示用空方法实现接口是一个坏主意。
有谁能说出为什么以上可能是个坏主意?或者它实际上是个好主意吗?
答案 0 :(得分:3)
您所描述的内容称为Null Object pattern。 Martin Fowler创造了这个术语,并在书Patterns of Enterprise Application Architecture中详细解释了它。
我认为这是一个很好的模式,可以删除代码中的所有if条件以检查not null。一个缺点可能是您必须在开发团队中解释一个模式,并且可能添加一条关于不在NullLog类中添加功能的注释。否则我无法找到这种模式的缺点。