juan_gandhi: (Default)
Juan-Carlos Gandhi ([personal profile] juan_gandhi) wrote2010-02-10 04:48 pm

синглтоны

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

Так я о чём? Да вот: синглтон класса - это примерно как поименованная общая область. Вот вам имя, вот вам инстанс, и делайте вы с этим что хотите.

Тьфу.

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

[identity profile] itman.livejournal.com 2010-02-11 03:37 am (UTC)(link)
Зря я все-таки потер. Все-таки, это получается синглтон. Можно считать, что есть функция
GetFileOpenIfClose(int FileNumber)
В парадигме синглтона, это решается заведение синглтона на каждый файл. Код инициализации синглотона также открывает файл. И можно в двух словах объяснить, как передача интерфейса поможет заменить синглтон? Или Вы имеете в виду интерфейс в смысле COM-объектов? Но так ведь там все равно возникает проблема однократной инициализации объекта. Чем это не синглтон.

[identity profile] qehgt.livejournal.com 2010-02-11 04:13 am (UTC)(link)
>как передача интерфейса поможет заменить синглтон?
Было:
void MyClass::foo()
{
   ... bla-bla
   OurCoolUtils::Logger::getInstance()->write("Finish bla");
   ... boo-boo
}

Стало:
MyClass::MyClass(........, ILogger* logger) 
  : .... logger(logger)
{
  ...
}

void MyClass::foo()
{
   ... bla-bla
   logger->write("Finish bla");
   ... boo-boo
}

[identity profile] qehgt.livejournal.com 2010-02-11 04:16 am (UTC)(link)
В реальных программах, конечно, передаваётся ссылка или используется smart pointer.

Всё для того же - сэкономить время в будущем.

[identity profile] itman.livejournal.com 2010-02-11 05:03 am (UTC)(link)
А, я понял. Вы не хотите, чтобы в коде везде был getInstance(). Это ИМХО очень правильный подход :-)
Но все равно придется написать:
MyClass SomeVar(...,OutCoolUtils::Logger::getInstance())

Или инициализировать OutCoolUtils::Logger глобально.

[identity profile] itman.livejournal.com 2010-02-11 05:08 am (UTC)(link)
Только я, возможно, забыл сказать, что в вышеприведенной задачке нельзя инициализировать объект глобально. Потому что инициализации и переинициализация наступает уже после старта программы.