А если надо объект БД использовать в нескольких разных классах, не связанных абстрактным классом реализующим setAdapter()?мне сложно у меня в приложении 1 синлетон - главный аппликейшен.
Все модели наследуют абстрактный класс модели в котором при инитиализации делается
PHP:$this->setAdapter( Core_Application::getInstance()->getAdapter() );
а это такая большая проблема? Я рефакторингом порой часами занимаюсь и сменить имя класса в двух-трех местах - самое безобидное с точки зрения моих рефакторингов задача.А у тебя если захочешь датабасе сменить - надо переписывать класс или во всем скрипте менять название класса.
я не защитник,я просто пытаюсь понять.займу позицию защитников синглтонов
Нужен мне адаптер PDO, MySQLi, Oracle или Postgre я его определю в бутстрапе апликейшена.grigori написал(а):Я действительно не понимаю, что такое "нужное", что подменять и когда
Если мне надо 2 базы я сделаю еще фабрику и буду оттуда ее тягать, но в 99% не нужно, лично мне. Когда надо, я делал так - переопределял в моделе констракт на:grigori написал(а):Я предложил DB_DEFAULT потому что не знаю, как ты инициализируешь 2ю базу. Из твоего примера совсем непонятно, как получить 2 объекта для работы с 2мя базами.
public function __construct()
{
$this->setAdapter( Core_Db::factory( 'MySQLi', 'localhost', 'root', '' )->setDatabase('requests') );
}
Сет адаптер вызывается в бутстрапе апликейшена. Апликейшен ты как раз можешь получить через синглетон(вот тут он очень уместен и как одиночка и как доступ) и запросить у него адаптер.Духовность™ написал(а):А если надо объект БД использовать в нескольких разных классах, не связанных абстрактным классом реализующим setAdapter()?
Да, потому что я делаю фреймоврк, а не готовое решение на 1 раз. Если ты в нем что-то поправишь, как ты будешь обновлять версии? Каждый раз что-то правя?)Духовность™ написал(а):а это такая большая проблема? Я рефакторингом порой часами занимаюсь и сменить имя класса в двух-трех местах - самое безобидное с точки зрения моих рефакторингов задача.
А бутстрап - это не код?я могу в бутстрапе подкинуть ... Ты такого сделать не можешь, не изменяя код.
Дальше я могу налету заменить адаптер, ты нет.
Это не код. Это установки конкретного приложения.А бутстрап - это не код?
чтоб сменить базу мне надо сделать иньекцию этого объекта. Тебе - переопределить DB_DEFAULT в сеттинге, то есть изменить параметр фабрики(гадаю).
В контексте обсуждения синглтона самое интересное - работа с несколькими базами. У меня такое бывает не так чтоб уж совсем редко.Если мне надо 2 базы я сделаю еще фабрику и буду оттуда ее тягать,
Как и все, я работаю не напрямую с драйвером, а через обертку/фасад, который реализует интерфейс.я могу в бутстрапе подкинуть не просто адаптер MySQLi а расширенный адаптер, реализующий главное интерфейс Core_Db_Adapter_Interface. Ты такого сделать не можешь, не изменяя код.
Что значит "налету"?я могу налету заменить адаптер, ты нет.
IMHO определение параметров подключения к базе в классе модели - хуже, чем использование константы в случаея делал так - переопределял в модели констракт
Вот именно, ты сам себе противоречишь. Одиночка, но в тоже время 2 объекта соединения.В контексте обсуждения синглтона самое интересное - работа с несколькими базами. У меня такое бывает не так чтоб уж совсем редко.
Тягать из фабрики ты будешь так же передавая параметр.
Смысл не в том через что ты работаешь, а как ты его подменить можешь. Если можешь, отлично.Как и все, я работаю не напрямую с драйвером, а через обертку/фасад, который реализует интерфейс.
Значит что я на протяжении запуска апликейшена могу изменить адаптер через какой я работаю по всему приложению, просто назначив другой драйвер, а ты?Что значит "налету"?
Параметры можно тягать из бутстрапа или сеттинга, то я сделал костыль для 1 места, вот и все, не заморачиваясь. Как сделать правильно я уже говорил.IMHO определение параметров подключения к базе в классе модели - хуже, чем использование константы в случае
Core_Application::getAdapter(DB_ANOTHER)
Разве нет?
ПХП не многопоточный(да-да-да), а значит есть только 1 апликейшен работающий в данный момент. Он всегда один(уже напрашивается одиночка), получая его - ты гарантированно попадешь на нужное тебе окружение используя его интерфейс и не плодя лишних не нужных одиночек, регистров и т. д.Смысл существования этого единого ядра я пока пытаюсь понять
Я не использую синглтоны вообще. У меня ощущение, что ты не понял мой вопрос.Вот именно, ты сам себе противоречишь. Одиночка, но в тоже время 2 объекта соединения.
Вопрос был о том, почему ты вызываешь статический метод для получения объекта для того, чтобы получить другой объект, вместо того, чтобы получать нужный объект прямо.Да я буду тягать с параметром, но не из синглетона который на это не расчитан, хотя и делаются getInstanse( DB_SOME );
Ничего не мешает мне заменить текущий объект подключения на другой.Значит что я на протяжении запуска апликейшена могу изменить адаптер через какой я работаю по всему приложению, просто назначив другой драйвер, а ты?
class Operator{
/**
* Object of the database connection
*
* @var gksPDO
*/
public $DB;
/**
* Default database connection object
*
* @var gDB
*/
static private $defaultDB;
//...
}
class DB extends Operator{
function getUrlList(ModelPaginator $Paginator){
$sql = 'select SQL_CALC_FOUND_ROWS id,added,use_frame from short_links'.
$Paginator->generateLimitClause();
$Redirects = $this->DB->getResultsCollection($sql,'RedirectRecord');
return $Redirects;
}
}
Как из определения "всегда один апликейшен" следует вывод "уже напрашивается одиночка"? По мне - совсем не напрашивается.ПХП не многопоточный(да-да-да), а значит есть только 1 апликейшен работающий в данный момент. Он всегда один(уже напрашивается одиночка)
Если у тебя всегда "только 1 апликейшен", работающий в один поток, как у него могут быть непредсказуемое или неправильное окружение? Окружение - это ведь тоже объекты, которые ты сам и формируешь, и оно тоже "одно", как и приложение.получая его - ты гарантированно попадешь на нужное тебе окружение используя его интерфейс и не плодя лишних не нужных одиночек, регистров и т. д.
Писал, покрывал, нормально. Нет проблем заменить self::$defaultDB на мок или еще как-то.у тебя код покрыт тестами?
Опять же - если этот объект будет "настраиваемым", то война всё равно будет....Или например - одиночка - это master proccess - для апаче.
Вот задача одиночки - быть уверенным , что он один, на всем протяжении работы приложения, и не боятся, что появится некто еще, у которого такие же как у него задачи, и не начнеттворить анархию в системе и не объявит войну.