Функция? Класс?

Я пишу приложение (C #), и иногда мне нужно будет войти в журнал событий Windows. Итак, первое, что приходит в голову, - это написать функцию в моем единственном классе и вызывать ее, когда мне это нужно. Что-то вроде этого:

private void Write_Event_Log(string log, string source, string message, EventLogEntryType type, int eventid)
    {
        if (!EventLog.SourceExists(source))
            EventLog.CreateEventSource(source, log);

        EventLog.WriteEntry(source, message, type, eventid);
    }

Мой коллега спросил: «Почему вы просто не создали новый класс для записи журнала событий?» Итак, мой вопрос, зачем мне это? И как бы вообще выглядел этот класс? И зачем мне это, если моя функция работает нормально? хорошо, это 3 вопроса, но вы поняли :)


person Jimmy D    schedule 19.08.2011    source источник
comment
Если ваше приложение настолько мало, что у вас есть один-единственный класс и вы вызываете его, когда он мне нужен, держите его внутри своего класса, но довольно редко требуется только один класс. Насколько велик этот класс?   -  person Mark Robinson    schedule 19.08.2011
comment
Создание источника событий требует административных привилегий. Это должно выполняться во время установки, а не динамически во время выполнения.   -  person Greg D    schedule 19.08.2011
comment
Это приложение представляет собой плагин, который загружается приложением, работающим как локальная системная учетная запись, поэтому проблем с безопасностью нет.   -  person Jimmy D    schedule 19.08.2011


Ответы (7)


Это очень общий вопрос об объектно-ориентированном дизайне. Ваш коллега имеет в виду разделение обязанностей; он не думает, что идея автора журнала событий вписывается в абстракцию класса, в который вы его поместили, и заслуживает своего собственного.

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

Написанная вами функция - это небольшая функция, которая не сохраняет состояние, поэтому другой класс на самом деле не нужен, если только он не помогает избежать проблем в будущем.

person Jeremy    schedule 19.08.2011

Зачем мне?

Инкапсулировать функцию ведения журнала в отдельный класс. Почему? Принцип единой ответственности http://en.wikipedia.org/wiki/Single_responsibility_principle. Смешивая его с вашим классом, вы заставляете этот класс отвечать как минимум за две (2) вещи: все, что он делает, и ведение журнала.

И как бы вообще выглядел этот класс?

public class LogWriter
{
    public static Log(string log, string source, string message, EventLogEntryType type, int eventid)
    {
        if (!EventLog.SourceExists(source))
            EventLog.CreateEventSource(source, log);

            EventLog.WriteEntry(source, message, type, eventid);
    }
}

И зачем мне это, если моя функция работает нормально?

Подумайте, когда вы перестанете отвечать за код. Думайте заранее, когда код вырастет. В конце концов, помимо ведения журнала, в него может быть включено множество других очень полезных функций. Следующий программист был бы намного счастливее, если бы ему не пришлось реорганизовывать вашу работу, потому что был создан прецедент дизайна.

person Ken Brittain    schedule 19.08.2011

Все просто: что, если вы хотите использовать этот метод повсюду во всех других частях вашего кода? Вы снова копируете - вставляете. Вместо этого имейте помощника или Add в классе, где просто создайте экземпляр и продолжайте звонить.

Кроме того, если он находится в классе, вы можете иметь больше свойств и предоставлять больше методов настройки, а также в данных журнала.

Посмотрите, сможете ли вы использовать встроенный журнал событий / трассировку.

person Zenwalker    schedule 19.08.2011

Если это небольшое приложение (которое должно быть с одним классом), это, вероятно, не имеет значения.

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

person Tridus    schedule 19.08.2011

По той же причине, что кто-то поместил SourceExists(Source) и CreateEventSource(source, log) в свой собственный класс, чтобы вы могли вызвать их, просто сославшись на сборку, в которой определен этот класс, и написав

 EventLog.SourceExists(source);

or

 EventLog.CreateEventSource(source, log);

Так что, если вам никогда не потребуется писать в журнал событий в любом другом приложении, которое вы когда-либо писали, то то, что вы делаете, в порядке ... но если вы когда-нибудь сможете нужно это снова, тогда ...

person Charles Bretana    schedule 19.08.2011

Я думаю, у вас должен быть отдельный класс, потому что, если вы собираетесь создать больше классов в своем приложении, вы можете использовать одно и то же ведение журнала для всех из них, см. Ниже пример общедоступного статического класса Logger {private static string logFilePath = string.Empty;

    public static void Log(string logMessage, TextWriter w)
    {
        w.Write( logMessage);
        w.Flush();
    }


    public static void Log(string textLog)
    {
        string directoryString =
      filepath+           @"\Logging";
        Directory.CreateDirectory(directoryString);

        logFilePath = directoryString + "\\" +
          DateTime.Now.ToShortDateString().Replace("/", "") + ".txt";


        StreamWriter sw = null;
        if (!File.Exists(logFilePath))
        {
            try
            {
                sw = File.CreateText(logFilePath);
            }
            finally
            {
                if (sw != null) sw.Dispose();
            }
        }
        using (StreamWriter w = File.AppendText(logFilePath))
        {
            Log(textLog, w);
            w.Close();
        }
    }
person 62071072SP    schedule 19.08.2011

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

Рассмотрите возможность использования встроенных механизмов отладки / трассировки в System.Diagnostics:

Debug output

Trace output

Это стандартные классы, которые выгружают информацию в коллекцию из TraceListener объектов, многие из которых уже существуют полезными типами:

DefaultTraceListener - выводит вывод для стандартной отладки, I верю через OutputDebugString().

EventLogTraceListener - выводит вывод в журнал событий Windows.

Таким образом, это меняет ваш механизм вывода с программного вопроса на вопрос конфигурации. (Да, если вы работаете в прямом управляемом приложении, вы можете заполнить свою коллекцию TraceListener через app.config.) Это означает, что везде вы просто используете соответствующий вызов Trace.Write() или Debug.Write() (в зависимости от того, хотите ли вы, чтобы результат в сборке выпуска), а конфигурация определяет, куда направляется вывод.

Конечно, вы также можете заполнить свою TraceListener коллекцию программно, это весело и просто.

Таким образом, вам не нужно создавать собственную инфраструктуру для лесозаготовок. Все встроено! Используйте его на здоровье! : D


Если же, с другой стороны, вы настаиваете на использовании своей собственной (я думаю, это плохая идея), ваш коллега прав. Это отдельная ответственность и относится к отдельному классу. Я ожидал бы статических методов для вывода, потому что, вероятно, нет концептуальных экземпляров вашего журнала отладки. Фактически, я ожидал, что интерфейс будет очень похож на System.Diagnostics.Debug, так что да, просто используйте его.


В зависимости от вашего подхода вы можете столкнуться с тонкой ошибкой, которая есть в документации, но не сразу очевидна без внимательного прочтения. Я нашел ответ в другом месте.

person Greg D    schedule 19.08.2011