这个班级最好的设计是什么?

时间:2011-01-09 10:49:42

标签: c# .net static class-design instance

假设这个类:

public class Logger
{
    static TextWriter fs = null;

    public Logger(string path)
    {
        fs = File.CreateText(path);
    }

    public static void Log(Exception ex)
    {
        ///do logging
    }

    public static void Log(string text)
    {
        ///do logging
    }
}

我必须使用它:

Logger log = new Logger(path);

然后使用Logger.Log()记录我想要的内容。我只使用一台记录仪。 问题是:这是一个很好的设计吗?实例化一个类然后总是调用它的静态方法?任何有关更好设计的建议产量都表示赞赏。

根据Marc的答案进行修改:

我在日志的最后一行刷新,并且在打开时不需要我读取文件,文件未完全关闭的问题是正确的。这个类只是满足我的要求,并且不需要线程安全。我只想阅读实例化部分,我应该进入你说的SetPath,关闭文件的任何建议吗?

3 个答案:

答案 0 :(得分:3)

是的,有一个构造函数只是为了这个是糟糕的设计。一个静态的SetPath方法可以只调用一次(否则抛出异常)似乎更好。您可以在app-startup等期间设置路径

然后,如果需要满足某些基于接口的方案,您可以将其设为static class或单例。

下一步:你必须在这里添加同步!这不是线程安全的。如果两个线程同时尝试登录,我预计会崩溃。它不需要复杂;最简单的:

private readonly object syncLock = new object();
public static void Log(string value) {
    lock(syncLock) {
        //...
    }
}

(但请注意,这可能会产生一些阻止成本;可以使用更复杂的代码进行改进 - 见下文)

现有的日志记录库会考虑更多问题 - 文件分区,异步(以阻止代码被IO阻止),批处理等;为什么不只使用其中之一?特别是,在te-moment,您的文件将不会在app-exit处完全关闭,不会定期刷新,并且会在大多数时间保持文件锁定状态。不好。

答案 1 :(得分:3)

不,这没有意义。每次实例化Logger时,都会覆盖静态TextWriter,这将影响该类的所有使用者。如果你想保留实例构造函数,那么你应该让TextWriter成为一个实例字段,方法应该是实例方法。

作为替代方案,您可能需要考虑使用log4net,它将为您执行此类日志记录工作。

答案 2 :(得分:0)

我认为你应该使用静态属性使整个类静态,允许你设置日志路径。

public static class Logger
{
    static TextWriter fs = null;

    public static string FileName
    {
      set
      {
        fs = File.CreateText(value);
      }
    }

    public static void Log(Exception ex)
    {
      if(fs == null) return;
        ///do logging
    }

    public static void Log(string text)
    {
      if(fs == null) return;
        ///do logging
    }
}