если я хочу построить класс logger в c ++ или java, то он должен быть одиночным или статическим - PullRequest
4 голосов
/ 04 апреля 2010

общий вопрос: мне нравится создавать класс логгера, который пишет в один лог-файл из разных классов в моем приложении, что должен быть класс регистратора синглетный или статический класс

Ответы [ 6 ]

8 голосов
/ 04 апреля 2010

Что заставляет вас думать, что так и должно быть?Как насчет обычного нестатического класса, который может быть создан по требованию?А затем сделать один статический экземпляр его доступным в качестве регистратора по умолчанию.Таким образом, вы получаете лучшее из обоих миров: удобный глобальный доступ к логгеру и , возможность протестировать его или временно использовать другой регистратор.

Другое предложение - просто создать один экземпляри передайте его в качестве параметра каждому компоненту вашего класса, как предполагает @disown.

Но если вы делаете класс статичным или одиночным, вы просто стреляете себе в ногу.

Edit
Пример, в ответ на @Комментарий Стивена:

// define a logger class, a perfectly ordinary class, not a singleton, and without all static members
class Logger {
 // ....
};

// create a single global *instance* of this class
Logger defaultLog;

void foo() {
  // and now use the globally visible instance
  defaultLog.Log("hello");

  // or create a new one if that's what we need:
  Logger newlog;
  newlog.Log("hello");
}

Там нет магии.Это именно то, что делает стандартная библиотека.std::cout не одиночка.Это просто глобальный экземпляр класса std::ostream, класса, который также может быть создан обычным образом, если и когда вам это нужно.

3 голосов
/ 04 апреля 2010

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

Я не уверен насчет Java.

0 голосов
/ 04 апреля 2010

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

MySuperSpectacularLogger::GetInstance()->Log("adssdf");

Вместо этого используйте:

void Log(cpnst string& msg) {
  MySuperSpectacularLogger::GetInstance()->Log(msg);
}

или даже лучше:

// Logs 'msg' with the filename and line number that generates it.
#define LOG(msg) \
  MySuperSpectacularLogger::GetInstance()->Log(__FILE__, __LINE__, msg);
0 голосов
/ 04 апреля 2010

В C ++ вы бы использовали эту идиому для ленивой инициализации:

Foo& getInstance()
{
    static Foo instance;
    return instance;
}
0 голосов
/ 04 апреля 2010

Не используйте singleton или static, используйте Dependency Injection, т.е. создайте экземпляр одного экземпляра в main () и передайте ссылку на этот экземпляр всем зависимым классам. Статика и / или синглтон почти никогда не нужны и часто приводят к менее элегантному коду.

0 голосов
/ 04 апреля 2010

Ответ, конечно, «это зависит».

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

...