仅使用空方法的接口实现

时间:2014-04-29 13:58:20

标签: c# .net oop interface abstract-class

我在应用程序中使用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();
        }
}

这种方法对我来说似乎更面向对象,所以我认为我喜欢它,但谷歌搜索似乎揭示了人们暗示用空方法实现接口是一个坏主意。

有谁能说出为什么以上可能是个坏主意?或者它实际上是个好主意吗?

1 个答案:

答案 0 :(得分:3)

您所描述的内容称为Null Object pattern。 Martin Fowler创造了这个术语,并在书Patterns of Enterprise Application Architecture中详细解释了它。

我认为这是一个很好的模式,可以删除代码中的所有if条件以检查not null。一个缺点可能是您必须在开发团队中解释一个模式,并且可能添加一条关于不在NullLog类中添加功能的注释。否则我无法找到这种模式的缺点。