Каков лучший дизайн для этого класса? - PullRequest
3 голосов
/ 09 января 2011

предположим, что этот класс:

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() для регистрации того, что я хочу.Я просто использую один Logger.вопрос: это хороший дизайн?создать экземпляр класса, а затем всегда вызывать его статический метод?приветствуется любая рекомендация в лучшем дизайне.

Редактирование на основе ответа Marc :

Я сбрасываю на последней строке журнала, и мне это не нужночтобы прочитать файл, пока он открыт, проблема с не полностью закрытым файлом является правильной.этот класс просто удовлетворяет моим требованиям, и нет необходимости в обеспечении безопасности потока.Я просто хочу прочесть раздел об инстанцировании, я должен попасть в SetPath, который вы сказали, какие-либо предложения по закрытию файла?

Ответы [ 3 ]

3 голосов
/ 09 января 2011

Нет, это не имеет смысла.Каждый раз, когда создается экземпляр Logger, статический TextWriter будет перезаписываться, что повлияет на всех потребителей класса.Если вы хотите сохранить конструктор экземпляра, то вы должны сделать TextWriter полем экземпляра, а методы должны быть методами экземпляра.

В качестве альтернативы вы можете рассмотреть возможность использования log4net, который будет вести этот вид журналирования.работа для вас.

3 голосов
/ 09 января 2011

Да, иметь конструктор только для этого - плохой дизайн. Статический метод SetPath, который можно вызывать только один раз (иначе выдает исключение), может показаться лучше. Вы должны указать путь при запуске приложения и т. Д.

Тогда вы можете сделать его либо static class, либо синглтоном, если это требуется для удовлетворения некоторого интерфейсного сценария.

Далее: вы должны добавить синхронизацию здесь! Это не потокобезопасно. Если два потока попытаются войти в систему одновременно, я ожидаю, что это ужасно рухнет. Это не должно быть сложным; самое простое:

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

(но учтите, что это может повлечь за собой некоторые затраты на блокировку; это можно улучшить с помощью более сложного кода - см. Ниже)

Существуют существующие библиотеки журналов, которые будут думать о множестве других проблем - разбиение файлов на части, асинхронность (для предотвращения блокировки вашего кода IO), пакетная обработка и т. Д .; почему бы просто не использовать один из них? В частности, в данный момент ваш файл не будет закрыт при выходе из приложения, не будет регулярно сбрасываться и большую часть времени будет держать файл заблокированным. Не хорошо.

0 голосов
/ 09 января 2011

Я думаю, вы должны сделать весь класс статическим со статическим свойством, позволяющим вам установить путь к журналу.

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
    }
}
...