Singleton vs namespace функции
От: Аноним  
Дата: 08.03.12 14:02
Оценка:
Иногда я использую синглетоны в своем коде.
В основном чтобы сделать менеджеры и вынести функции к которым нужно получать доступ откуда угодно.

Однако встретил статью, которая описывает почему синглетоны плохи и что нужно создавать вместо них свободные функции,
объединенные в общий namespace:
http://itw66.ru/blog/c_plus_plus/65.html
http://itw66.ru/blog/c_plus_plus/71.html

Так как лучше поступать? Создавать синглетоны или свободные функции? Или есть критерии выбора метода?
Re: Singleton vs namespace функции
От: innochenti  
Дата: 08.03.12 14:34
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Иногда я использую синглетоны в своем коде.

А>В основном чтобы сделать менеджеры и вынести функции к которым нужно получать доступ откуда угодно.

А>Однако встретил статью, которая описывает почему синглетоны плохи и что нужно создавать вместо них свободные функции,

А>объединенные в общий namespace:
А>http://itw66.ru/blog/c_plus_plus/65.html
А>http://itw66.ru/blog/c_plus_plus/71.html

А>Так как лучше поступать? Создавать синглетоны или свободные функции? Или есть критерии выбора метода?

почитайте еще http://users.livejournal.com/_winnie/18677.html
Re: Singleton vs namespace функции
От: Константин Россия  
Дата: 08.03.12 18:53
Оценка: 2 (2)
Здравствуйте, Аноним, Вы писали:

А>Иногда я использую синглетоны в своем коде.

А>В основном чтобы сделать менеджеры и вынести функции к которым нужно получать доступ откуда угодно.

А>Однако встретил статью, которая описывает почему синглетоны плохи и что нужно создавать вместо них свободные функции,

А>объединенные в общий namespace:
А>http://itw66.ru/blog/c_plus_plus/65.html
А>http://itw66.ru/blog/c_plus_plus/71.html

А>Так как лучше поступать? Создавать синглетоны или свободные функции? Или есть критерии выбора метода?


Хрен редьки не слаще. Предложенный в статье вариант все равно работает с глобальным объектом. Даже хуже, синглтонный класс обычно видно издалека, и ясно какие проблемы можно огрести, его используя. Функции же прикидываются обычными функциями, не акцентируя внимания на том, что они, по большому счету являются методами синглтона. Как итог, вероятность ошибочного использования таких функций кажется выше.
Re: Singleton vs namespace функции
От: MasterZiv СССР  
Дата: 08.03.12 22:10
Оценка:
> Однако встретил статью, которая описывает почему синглетоны плохи и что нужно
> создавать вместо них свободные функции,

Зачем читать всякую чушь в интернете а потом ещё предлагать всем её обсуждать
?

Сотри ты этот сайт из памяти, и всё.
Posted via RSDN NNTP Server 2.1 beta
Re: Singleton vs namespace функции
От: okman Беларусь https://searchinform.ru/
Дата: 09.03.12 08:10
Оценка: 3 (3) +2
Здравствуйте, Аноним, Вы писали:

А>Так как лучше поступать? Создавать синглетоны или свободные функции? Или есть критерии выбора метода?


Откажитесь от синглетонов вообще. Как и от функций, предназначенных для того, чтобы их
можно было вызывать "откуда угодно". Худшее, что можно придумать, особенно для библиотечного
кода с хоть какими-то перспективами на повторное использование в других проектах, — это
задействованный в куче исходных файлов синглетон, сам зависимый еще от десятка классов.
Еще хуже, когда зависимость проникает не только в реализацию, но и в интерфейс (заголовки).
Получите не код, а монолитный кусок, один компонент которого будет тянуть за собой
зависимости от большинства остальных. Я от синглетонов отказался очень давно, и за последние
года полтора-два не припомню ни одного случая, чтобы они оказались где-то реально полезными.

Существование всяких менеджеров, диспетчеров и координаторов — это, как правило, признак не
очень хорошей архитектуры. Обычно эти классы имеют тенденцию довольно быстро разрастаться,
чтобы включать в себя вся и все. Эдакий антипаттерн с двадцатью полями и полсотней методов.

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

Если синглетон выполняет контроль за инициализацией неких объектов, то эту инициализацию
можно централизовать в отдельном исходном файле. По крайней мере, его можно будет легче
переписать, чем бегать по всему коду с find/replace.

Синглетон — очень вредный паттерн, и место ему лишь в совершенно исключительных ситуациях,
когда все остальное невозможно. В противном случае лучше отказаться от его использования.
Re[2]: Singleton vs namespace функции
От: Sni4ok  
Дата: 09.03.12 15:31
Оценка:
Здравствуйте, okman, Вы писали:

O>Откажитесь от синглетонов вообще.


была функция, а потом опа- и захотелось логировать из неё что-то, как тут без синглтона?
Re[2]: Singleton vs namespace функции
От: Ops Россия  
Дата: 09.03.12 16:01
Оценка: +3
Здравствуйте, okman, Вы писали:

Менеджер памяти, логгер, глобальные настройки программы — как с ними быть? Таскать во все классы/функции раздутый контекст, созданный динамически? Или таскать по несколько таких контекстов, не таких раздутых?
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Re[3]: Singleton vs namespace функции
От: okman Беларусь https://searchinform.ru/
Дата: 09.03.12 18:29
Оценка: 1 (1) +1
Здравствуйте, Ops, Вы писали:

Ops>Менеджер памяти, логгер, глобальные настройки программы — как с ними быть? Таскать во все классы/функции раздутый контекст, созданный динамически? Или таскать по несколько таких контекстов, не таких раздутых?


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

Вариант 1.
class splashscreen
{
public:
    splashscreen()
    {
        // Settings и Memory - глобальные объекты или синглетоны.
        std::wstring ImagePath = Settings.splash_image_path();
        load_image(ImagePath, Memory.default_allocator());
    }

// ...

};


Первый вариант плох, потому что вводит зависимость splashscreen от Settings и Memory.
Если splashscreen потребуется использовать в другом проекте, он потянет за собой и
их тоже, а также их собственные зависимости. Короче, получится набор классов, жестко
связанных между собой, которые трудно задействовать где-то еще по отдельности.

Есть и другая проблема, которая не бросается в глаза — инициализация Settings и Memory.
Если до вызова конструктора splashscreen они не были задействованы, будут вызваны и их
конструкторы тоже. То есть, происходит неявная инициализация Settings и Memory по месту
создания splashscreen. А они могут бросать исключения, например. Или со временем что-то
изменится так, что Settings будет зависеть от Memory и конструктор Memory всегда нужно будет
вызывать первым. Представьте себе набор из нескольких десятков классов, в которых происходит
неявная инициализация Settings и Memory, причем в разном порядке относительно друг друга, и
неизвестно, объект какого именно класса будет создан первым (запускаться могут несколько
потоков, к примеру).

Вариант 2.
class splashscreen
{
public:
    // allocator - абстрактный класс.
    splashscreen(std::wstring const &ImagePath,
        allocator const &Allocator)
    {
        load_image(ImagePath, Allocator);
    }

// ...

};


Второй вариант лучше. Во-первых потому, что осталась зависимость только от абстрактного
allocator, который можно определить любым образом, в зависимости от требований,
перетащить в другой код с минимальными корректировками, а ImagePath и Allocator можно
задавать где-нибудь в main или в специальной фабрике, которая создает splashscreen,
и это будет намного более гибко. Вопрос инициализации Settings и Memory, а также
порядка этой инициализации, тоже снимается, так как она выносится в специально
отведенное место программы (в ту же main, к примеру), и выполняется централизованно:

int main()
{
    // Инициализация сосредоточена в одном месте, порядок определен.
    memory        Memory;
    settings      Settings;

    // Никаких зависимостей splashscreen от прочих объектов.
    splashscreen  Splash(Settings.get_splash_file(), Memory.get_allocator());

    // ...

    return 0;
}


Вот мы и приходим к тому, что синглетоны и глобальные объекты не только не нужны, но
еще и просто опасны.
Re[3]: Singleton vs namespace функции
От: okman Беларусь https://searchinform.ru/
Дата: 09.03.12 18:40
Оценка: +1
Здравствуйте, Sni4ok, Вы писали:

S>была функция, а потом опа- и захотелось логировать из неё что-то, как тут без синглтона?


Допускаю.
Но логгеры бывают разные. Например, трассировка применяется для поиска какой-нибудь
ошибки в программе, когда ее не получается поймать в отладке или тестами.
Но такие трассировочные логгеры долго не живут — их в релизных версиях либо отключают
(всякие #ifdef/#undef), либо, протестировав нужные компоненты, вообще вырезают
трассировочный код. Поэтому здесь использовать синглетон точно также плохо/хорошо,
как и макросы, либо глобальные объекты — ни на что они в конечном итоге влиять не
будут, в паблик не попадут и в API тоже. А если речь про запись всяких критических
сообщений в журнал (типа "Сервер запущен на таком-то порту", "Не удалось подключиться к
базе", и т.д.), то здесь еще выгоднее отказаться от синглетона в пользу некой другой
сущности, либо добавить хотя бы один уровень косвенности — через service locator, к примеру.

Я как-то задался целью — писать код совсем без глобальных объектов и без синглетонов,
если только на это нет ну совершенно исключительнейшей нужды. На удивление, это оказалось
довольно просто. Всем, кто не верит, искренне советую попробовать.
Re[4]: Singleton vs namespace функции
От: CreatorCray  
Дата: 09.03.12 19:14
Оценка: +3
Здравствуйте, okman, Вы писали:

O>
O>int main()
O>{
O>    // Инициализация сосредоточена в одном месте, порядок определен.
O>    memory        Memory;
O>    settings      Settings;

O>    // Никаких зависимостей splashscreen от прочих объектов.
O>    splashscreen  Splash(Settings.get_splash_file(), Memory.get_allocator());

O>    // ...

O>    return 0;
O>}
O>


Это очень простой пример. А вот если у нас не splashscreen что либо вызывающееся гораздо глубже, вожможно даже из WINAPI CALLBACK
Получается что надо всё что только может понадобиться на той глубине протаскивать через все вызовы. Это гемор ещё почище.

O>Вот мы и приходим к тому, что синглетоны и глобальные объекты не только не нужны, но

O>еще и просто опасны.

Всё полезно в меру. И синглтоны и глобальные объекты бывают крайне полезны и удобны, если без фанатизма.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[2]: Singleton vs namespace функции
От: trophim Россия  
Дата: 09.03.12 20:25
Оценка:
...мастер, как обычно, конструктивен.
... << RSDN@Home 1.2.0 alpha 5 rev. 1495>>
Let it be! — Давайте есть пчелу!
Re[3]: Singleton vs namespace функции
От: MasterZiv СССР  
Дата: 09.03.12 20:44
Оценка:
> ...мастер, как обычно, конструктивен.

Так статья-то не Страустрапа, и не Саттера.
Posted via RSDN NNTP Server 2.1 beta
Re[4]: Singleton vs namespace функции
От: Sni4ok  
Дата: 10.03.12 07:36
Оценка:
Здравствуйте, okman, Вы писали:

O>Но логгеры бывают разные.


вам пример привели, а вы в частности лезите, cout, new используете? ну так вот, они тоже к глобальным обьектам обращаются. Или типичный аллокатор который принимают стандартные контейнеры, как вы без глобального обьекта реализовывать будете? Если ваши задачи очень просты- и позволяют делать что угодно и как угодно, из этого не следует, что конекст использования с++ у всех такойже.
Re[5]: Singleton vs namespace функции
От: okman Беларусь https://searchinform.ru/
Дата: 10.03.12 09:29
Оценка:
Здравствуйте, Sni4ok, Вы писали:

S>вам пример привели, а вы в частности лезите, cout, new используете? ну так вот, они тоже к глобальным обьектам обращаются. Или типичный аллокатор который принимают стандартные контейнеры, как вы без глобального обьекта реализовывать будете?


Суть не в том, глобальный объект или нет, а в том, зависит ли он от других классов.
С cout, new/delete или контейнерами STL такого вопроса не возникает, потому что они
являются частью языка, и класс, их использующий, переносится в другой проект или на
другую архитектуру без лишних хлопот по этому поводу. А глобальные переменные или
синглтоны, задействованные в классе, вводят в него ненужные зависимости, и от таких
зависимостей нужно по возможности избавляться. С чем в этом утверждении Вы не согласны ?

S>Если ваши задачи очень просты- и позволяют делать что угодно и как угодно, из этого не следует, что конекст использования с++ у всех такойже.


Мои задачи таковы, что приходится разбивать их на ряд меньших по объему, а затем
прорабатывать по отдельности, в изоляции друг от друга. В достижении этого, в
числе прочего, ощутимо помогает отказ от синглтонов, глобальных объектов и других
форм зависимостей, потому что иначе компоненты банально неудобно ни тестировать,
ни использовать повторно.
Re[5]: Singleton vs namespace функции
От: MasterZiv СССР  
Дата: 10.03.12 10:09
Оценка:
> вам пример привели, а вы в частности лезите, cout, new используете? ну так вот,
> они тоже к глобальным обьектам обращаются. Или типичный аллокатор который
> принимают стандартные контейнеры, как вы без глобального обьекта реализовывать
> будете?

std::allocator как раз можно оздавать как временный объект, по стандарту
он лишён идентичности.
Posted via RSDN NNTP Server 2.1 beta
Re[5]: Singleton vs namespace функции
От: okman Беларусь https://searchinform.ru/
Дата: 10.03.12 10:18
Оценка:
Здравствуйте, CreatorCray, Вы писали:

CC>Всё полезно в меру. И синглтоны и глобальные объекты бывают крайне полезны и удобны, если без фанатизма.


Догматизм — он в любом деле вреден.
Кстати, я тут однажды уже расхваливал синглтоны — http://rsdn.ru/forum/cpp/3894680.aspx
Автор: okman
Дата: 27.07.10

А потом сам же и напоролся на их недостатки (надо бы в том сообщении себе минус поставить,
за неумышленное введение людей в заблуждение). Прошлись, так сказать, от и до — начиная с
порядка инициализации/разрушения и до невозможности извлечь отдельный компонент для теста,
чтобы не тащить за ним всю систему.

CC>А вот если у нас не splashscreen что либо вызывающееся гораздо глубже, вожможно даже из WINAPI CALLBACK

CC>Получается что надо всё что только может понадобиться на той глубине протаскивать через все вызовы. Это гемор ещё почище.

Если концы с концами сходятся так, что приходится прокладывать доступ через ряд посредников,
либо лепить синглтон/глобальный объект, то это повод в первую очередь задуматься о косяках
архитектуры (например, о том, что взаимодействие между application layers слишком тесное).
Но я думаю, это все понимают. И необходимость в таких объектах намного ниже, чем обычно
принято считать. Если не сказать, что она вообще микроскопическая. Например, в моих проектах
глобальных переменных, может, и наберется штук десять в совокупности, но синглтона нет ни
одного, это точно. И каких-то затруднений по этому поводу не испытываю.
Re[6]: Singleton vs namespace функции
От: Ops Россия  
Дата: 10.03.12 10:51
Оценка:
Здравствуйте, okman, Вы писали:

O>Например, в моих проектах

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

А в чем разница между глобальной переменной и синглтоном с точки зрения связности кода? А ведь это чуть ли не основной Ваш аргумент против них.
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Re[6]: Singleton vs namespace функции
От: CreatorCray  
Дата: 10.03.12 15:35
Оценка:
Здравствуйте, okman, Вы писали:

CC>>Всё полезно в меру. И синглтоны и глобальные объекты бывают крайне полезны и удобны, если без фанатизма.

O>Догматизм — он в любом деле вреден.
Отож!

O>Кстати, я тут однажды уже расхваливал синглтоны — http://rsdn.ru/forum/cpp/3894680.aspx
Автор: okman
Дата: 27.07.10

O>А потом сам же и напоролся на их недостатки (надо бы в том сообщении себе минус поставить,
O>за неумышленное введение людей в заблуждение).
Ну дык серебряной пули то нетЪ! (тм)
Потому и то, что в любом паттерне можно найти недостатки это как бы само собой разумеющееся. У тех же синглтонов есть область применения, для которых они закрывают собой определённых размеров проблемы. Но есть ситуации, где они не очень хорошо подходят. По крайней мере далеко не любая реализация синглтона.

O> Прошлись, так сказать, от и до — начиная с порядка инициализации/разрушения и до невозможности извлечь отдельный компонент для теста, чтобы не тащить за ним всю систему.

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

O>Если концы с концами сходятся так, что приходится прокладывать доступ через ряд посредников,

O>либо лепить синглтон/глобальный объект, то это повод в первую очередь задуматься о косяках
O>архитектуры (например, о том, что взаимодействие между application layers слишком тесное).

Порой прокладывать такие пути приходится из-за возникновения дополнительных требований, которые к тому же бывают довольно таки ортогональными изначальной архитектуре.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[4]: Singleton vs namespace функции
От: MescalitoPeyot Украина  
Дата: 10.03.12 15:41
Оценка:
Здравствуйте, okman, Вы писали:

O>то здесь еще выгоднее отказаться от синглетона в пользу некой другой

O>сущности, либо добавить хотя бы один уровень косвенности — через service locator, к примеру.

По факту, эта "сущность" и будет синглтоном. Косвенным. Правильно?
Re[7]: Singleton vs namespace функции
От: okman Беларусь https://searchinform.ru/
Дата: 10.03.12 16:30
Оценка:
Здравствуйте, Ops, Вы писали:

Ops>А в чем разница между глобальной переменной и синглтоном с точки зрения связности кода? А ведь это чуть ли не основной Ваш аргумент против них.


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

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

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

Далее. Синглтон привносит в использующий его код зависимость от политики контроля за
количеством экземпляров. Обычно это именно то, что требуется, но где гарантия, что на
определенном этапе вам не потребуется два и более экземпляра logger ? Когда это случится,
потребуется переписать все места, в которых вызывается singleton<logger>::get_instance(), и
не просто переписать, а учесть этот новый фактор надлежащим образом. Короче говоря, один
класс, использующий другой, не должен ничего "знать" про его контроль количества экземпляров.

Зато обычный указатель на базовый logger свободен от этих проблем, не говоря уже о более
приятном синтаксисе вызова — logger.write(...) вместо singleton<logger>::get_instance().write().

Необходимость поддерживать семантику get_instance приводит к тому, что классы-синглтоны
ограничены в способах конструирования, в то время, как обычные объекты можно создавать
через конструкторы, с аргументами и без, запрашивать у фабрик, брать из пула и т.д.

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

Обычные глобальные объекты, создаваемые в динамической памяти, тоже подвержены этим проблемам,
но там доступен целый спектр вспомогательных средств — смарт-поинтеры, подсчет ссылок, и т.п.

И при всем при этом, у синглтона вполне может быть разумно обоснованное применение,
более удачное остальных, вот только процент таких случаев — ноль целых, одна десятая.
Re[7]: Singleton vs namespace функции
От: okman Беларусь https://searchinform.ru/
Дата: 10.03.12 16:34
Оценка:
Здравствуйте, CreatorCray, Вы писали:

O>> Прошлись, так сказать, от и до — начиная с порядка инициализации/разрушения и до невозможности извлечь отдельный компонент для теста, чтобы не тащить за ним всю систему.

CC>Ну вот значит в том случае синглтон был неудачным выбором, исходя из требований.

Да нет, просто их применяли необдуманно. Лепили без разбору туда и сюда:
"Логгер ? Ок, будет синглтон. Управление параметрами службы — не проблема, вставим еще один
синглтон, нам не жалко. Компонент взаимодействия с сервером — ваще отлично, и этого туда же".
Re[5]: Singleton vs namespace функции
От: okman Беларусь https://searchinform.ru/
Дата: 10.03.12 16:38
Оценка:
Здравствуйте, MescalitoPeyot, Вы писали:

MP>По факту, эта "сущность" и будет синглтоном. Косвенным. Правильно?


Не совсем. Запрашивать объект через service locator или конструировать его сразу,
по месту вызова — это не одно и то же. Потому что в первом случае придется
сохранять где-то ссылку/указатель, плюс доступны стандартные "плюшки" виртуальности —
возможность использовать мок-объекты, например. И "знания" о том, что возвращенный
объект на самом деле является каким-то там Одиночкой, у клиентского кода не будет,
что, на мой взгляд, только к лучшему.
Re[6]: Singleton vs namespace функции
От: MescalitoPeyot Украина  
Дата: 10.03.12 17:45
Оценка:
Здравствуйте, okman, Вы писали:

O>Не совсем. Запрашивать объект через service locator или конструировать его сразу,

O>по месту вызова — это не одно и то же.

Ага. Т. е. синглтоном вы называете нечто кондовое, конструируемое по первому запросу с глобальной статической переменной, ссылкой или указателем который хранит единственный экземпляр этого синглтона. Правильно? Мне такой синглтон тоже не нравится и из-за многопоточности, и из-за отладки, и вообще. Инициализация явным образом в main/applicationDidFinishLaunching/JNI_OnLoad/и т. п. — наше всё.

O>И "знания" о том, что возвращенный

O>объект на самом деле является каким-то там Одиночкой, у клиентского кода не будет,
O>что, на мой взгляд, только к лучшему.

"Знание кода" о том что кто-то является синглтоном означает способность выполнить какие-либо действия, где отличие синглтона от несинглтона могут проявиться. В контексте кода получающего откуда-то сверху некий ContextObject или достающий это нечто из service locator или берущий это нечто у классического getInstance() различия между синглтоном и несинглтоном не видны.

O>возможность использовать мок-объекты, например


Ну вот разве что. Хотя я, как не фанат юнит-тестов, не понимаю зачем может понадобиться мокать классический логер или, скажем, реестр jclass'ов в JNI.
Re[8]: Singleton vs namespace функции
От: Ops Россия  
Дата: 10.03.12 19:05
Оценка:
Здравствуйте, okman, Вы писали:

O>Здравствуйте, Ops, Вы писали:


Ops>>А в чем разница между глобальной переменной и синглтоном с точки зрения связности кода? А ведь это чуть ли не основной Ваш аргумент против них.


O>Если задуматься, синглтон нисколько не лучше глобальных переменных, а даже хуже.


O>Синглтон реализуется через статические функции, поэтому абстрактные классы-интерфейсы,

O>применяющиеся в том числе и в целях уменьшения связности, для него использовать не
O>получится, и также не получится построить на базе класса-синглтона полиморфную иерархию
O>вроде file_logger/console_logger и т.п. Во всяком случае, это уже будет не синглтон.

O>В то же время обычный объект можно объявить как полиморфный указатель, и это ослабляет

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

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

O>Далее. Синглтон привносит в использующий его код зависимость от политики контроля за

O>количеством экземпляров. Обычно это именно то, что требуется, но где гарантия, что на
O>определенном этапе вам не потребуется два и более экземпляра logger ? Когда это случится,
O>потребуется переписать все места, в которых вызывается singleton<logger>::get_instance(), и
O>не просто переписать, а учесть этот новый фактор надлежащим образом. Короче говоря, один
O>класс, использующий другой, не должен ничего "знать" про его контроль количества экземпляров.

O>Зато обычный указатель на базовый logger свободен от этих проблем, не говоря уже о более

O>приятном синтаксисе вызова — logger.write(...) вместо singleton<logger>::get_instance().write().

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

O>Необходимость поддерживать семантику get_instance приводит к тому, что классы-синглтоны

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

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

O>Синглтоны вносят в код ненужные зависимости от порядка инициализации.

O>Терпимо, когда этот порядок регулируется автоматически, либо определяется централизованно, но
O>требования меняются, код меняется, в конце концов получаем какую-нибудь циклическую зависимость,
O>либо недетерминированный порядок (в многопоточных приложениях — особенно актуально).

O>Обычные глобальные объекты, создаваемые в динамической памяти, тоже подвержены этим проблемам,

O>но там доступен целый спектр вспомогательных средств — смарт-поинтеры, подсчет ссылок, и т.п.

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

O>И при всем при этом, у синглтона вполне может быть разумно обоснованное применение,

O>более удачное остальных, вот только процент таких случаев — ноль целых, одна десятая.

Так я же не призываю использовать синглтоны где ни попадя, вообще избегаю их, но не согласен, что от них стоит полностью отказываться и не считаю их бОльшим злом, чем глобальные объекты.
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Re[8]: Singleton vs namespace функции
От: CreatorCray  
Дата: 11.03.12 00:00
Оценка:
Здравствуйте, okman, Вы писали:

O>>> Прошлись, так сказать, от и до — начиная с порядка инициализации/разрушения и до невозможности извлечь отдельный компонент для теста, чтобы не тащить за ним всю систему.

CC>>Ну вот значит в том случае синглтон был неудачным выбором, исходя из требований.

O>Да нет, просто их применяли необдуманно. Лепили без разбору туда и сюда:

O>"Логгер ? Ок, будет синглтон. Управление параметрами службы — не проблема, вставим еще один
O>синглтон, нам не жалко. Компонент взаимодействия с сервером — ваще отлично, и этого туда же".

Я по сути говорил о том же.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.