Почему Singelton - плохая практика?

  • Автор темы Духовность™
  • Дата начала

AmdY

Пью пиво
Команда форума
lmbToolkit :: merge(new SpeakingTools ());
это точно объект создаётся не "внутри"
 

fixxxer

К.О.
Партнер клуба
Эээ, то где вы говорите про синглтон не как конкретную реализацию, а как единичный экземпляр - это же прекрасно делается через DI/IoC, только на правильном уровне (об "одиночности" решает среда а не сам класс)!
 

cDLEON

Онанист РНРСlub
Конкретно для ПХП синглтон это вообще полный антипаттерн. Потому как иногда нужно какой-нибудь код выполнить в другом коде. (например инклюд в шаблон)
От сюда куча геморроя с переключением всей этой статики (читай "синглтонов") на другие сервера, например. И не возможность работать после - без переопределения этих параметров подключения (опять же - например). И т.д.
Да и для любого объекта одиночки будь то юзер или там какой-нибудь абстрактный класс работы с БД - могут попадаться задачи вроде "создание ещё одного юзера", "взаимодействие двух юзеров", "использование двух подключений к БД".
Иногда, конечно, такие задачи решаются дополнительными параметрами в методах - но всё равно - всё это через зад. И расширяемости этому - ноль целых, ноль десятых.
 

Sherman

Mephi
In particular if you use a singleton (or other form of Registry) make sure that they can be easily substituted and that their initialization can also be easily replaced. (c) Fowler

p.s. А подменять надо конечно же через ваш любимый IoC контейнер.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
очередная тема из серии "что плохого в ..."
ответ опять очевиден
 

Духовность™

Guest
пока не будет примеров в этой теме, ответ совсем не очевиден
 

korchasa

LIMB infected
Я понял, что ты говоришь об синглтоне-экземпляре, а не о синглтоне-интерфейсе. Я тока не понял, что тебе мешает это сделать и где тут несоответствие с тезисом в #23 ?
Это не про соответствие с тезисом, это пример к моему опыту, в котором сиглтон-интерфейс(ака доступ из разных слоев) сильно пересекается с синглтоном-экземляром.
 

Духовность™

Guest
примеров зависимостей? или чего?
примеров как правильно делать. вот у меня,допустим, есть классы-мепперы. в конструкторе при инстанцировании этих классов вызывается
PHP:
$this->db = Database::getInstanse()
это вы говорите плохо. а как хорошо?
 

HraKK

Мудак
Команда форума
мне сложно у меня в приложении 1 синлетон - главный аппликейшен.
Все модели наследуют абстрактный класс модели в котором при инитиализации делается
PHP:
$this->setAdapter( Core_Application::getInstance()->getAdapter() );
А адаптер назначается в бутстрапе
PHP:
->setAdapter( Core_Db::factory( 'Mysqli',
						$Application->getParam( 'dbHost' , '127.0.0.1' ),
						$Application->getParam( 'dbUsername' , 'root' ),
						$Application->getParam( 'dbPassword' , '' ) ) );
Как бы синлетон, но не базы то есть мне чтоб сменить базу данных надо всего лишь в бутстрапе передать туда другие значения.
А у тебя если захочешь датабасе сменить - надо переписывать класс или во всем скрипте менять название класса.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
пока не будет примеров в этой теме, ответ совсем не очевиден
Это сиквел темы "чем плох ООП".
Он не может быть ни плохим, ни хорошим.
Использовать правильно - хорошо, неправильно - плохо.

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

grigori

( ͡° ͜ʖ ͡°)
Команда форума
например, HraKK, зачем ты пишешь
Core_Application::getInstance()->getAdapter()
а не
Core_Application::getAdapter(DB_DEFAULT)?

я не знаю, как реализован Core_Application, мне сложно понять - расскажи?
 

HraKK

Мудак
Команда форума
Core_Application::getAdapter(DB_DEFAULT)?
потому что легче вначале инициализировать нужное и подменять тогда когда мне надо, а не по всему коду бегать и изменять DB_DEFAULT на DB_ANOTHER.
Каг бы, неуместный вопрос вообще.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Эээ, то где вы говорите про синглтон не как конкретную реализацию, а как единичный экземпляр - это же прекрасно делается через DI/IoC, только на правильном уровне (об "одиночности" решает среда а не сам класс)!
согласен

можешь примерно схему среды набросать, как ты ее видишь?
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
потому что легче вначале инициализировать нужное и подменять тогда когда мне надо, а не по всему коду бегать и изменять DB_DEFAULT на DB_ANOTHER.
Каг бы, неуместный вопрос вообще.
Я верю, что фраза "я не знаю, расскажи пожалуйста " уместна.
Я не пытаюсь подначивать, просто хочу перевести топик из режима срача в обмен опытом.
Я действительно не понимаю, что такое "нужное", что подменять и когда
Никто не видел твой код, мы можем лишь смутно догадываться.
Я предложил DB_DEFAULT потому что не знаю, как ты инициализируешь 2ю базу. Из твоего примера совсем непонятно, как получить 2 объекта для работы с 2мя базами.

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

флоппик

promotor fidei
Команда форума
Партнер клуба
Ну, наверное, займу позицию защитников синглтонов.
У меня работа с несколькими базами реализуется так:
PHP:
$db = Database::instance(); // Вернет активное соединение с базой.
$db = Database::instance('secondary'); // Вернет нужное именованное соединение, есть ключевое слово default - по нему возвращается первое описанное в конфигурации соединение
$db = Database::uses('secondary'); // Вернет именованное соединение и сделает его активным
А конфиг содинения с базой в коде не храню, да. В extensions/database/bootstrap.php есть
PHP:
Database::init(Configuration::Load('configuration/database.php'));
configuration/database.php - это
PHP:
<?php
return array( настройки подключения );
?>
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
> Database::instance('secondary');
это не синглтон, а скорее регистр (вместо процедурного mysql поставь объекты mysqli/pdo)
> Database::uses()
с декоратором/прокси
 

флоппик

promotor fidei
Команда форума
Партнер клуба
Да, специализированный реестр, получается. Просто он эволюционировал из синглтона. )
grigori написал(а):
(вместо процедурного mysql поставь объекты mysqli/pdo)
?
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Я подумал, что у тебя могут в одном объекте храниться все хендлеры, полученные из mysql_conect, и вызовом ::uses ты на лету выставляешь активное.
Так формально можно обойтись одним объектом-синглтоном с несколькими базами.
Но, если вспомнить, что mysqli/pdo создают объекты - это уже наглядно реестр, и защитника синглтона из тебя не получилось ))
 
Сверху