Статичиеские методы и свойства, Singleton - разъясните

korchasa

LIMB infected
Автор оригинала: berkut
енто как
private static $varl;
завязан на имени класса
В вызове, а не в определении:
Foo::$bar
Соответственно у нас все клиенты теперь завязаны на имя класса, а не на его интерфейс.
 

Alexandre

PHPПенсионер
print_r($a); // объект пуст?
echo $a->getStr(); // выводит "привет!"
Объясните пожалуйста, почему print_r выводит пустой объект? Почему в выводе нет упоминания о переменной $str?
потому-что private static $str; переменная статическая.
не хочешь использовать статик, используй динамик ;)
Потому же почему и наследование хуже делегирования - статическая зависимость от имени класса.
что значить статическая зависимость от имени класса?
больше года использую синглетоны (но не злоупотребляю) и ни разу не жаловался.
 

korchasa

LIMB infected
Автор оригинала: Alexandre
что значить статическая зависимость от имени класса?
больше года использую синглетоны (но не злоупотребляю) и ни разу не жаловался.
Ну если мы пишем
PHP:
new Foo;
Foo::$a;
Foo::b();
Мы ожидаем, что во-первых есть объявленный класс Foo, во-вторых у класса Foo есть статическое свойство $a, и метод $b. Нам уже сложнее переименовать этот класс, т.к. на него могут быть завязаны клиенты. Проблема, конечно, не самом наличие такой зависимости, а в их возможном большом количестве. Попробуй, например, теперь переименовать один из синглтонов ;)

Автор оригинала: berkut
korchasa
а ничо шо
private static $bar;
Foo::$bar;
енто fatal error?
Каюсь не заметил private. Зависимость в данном случае не свойстве, а в вызове метода getInstance(), но меньше она от этого не становится. Поэтому и рекомендуется иметь в системе только один синглтон, чтобы свести количество зависимостей к минимуму.

И вообще зачем там private, если нет сеттера на инстанцию? Ее же теперь подменить невозможно.
 

Alexandre

PHPПенсионер
Поэтому и рекомендуется иметь в системе только один синглтон, чтобы свести количество зависимостей к минимуму.
чем плохо:
$db = DB::getInstance();
$sess = SESSIONS::getInstance();

какая может быть зависимость, если у нас два разных класса: DB и SESSIONS ?
 

master_x

Pitavale XXI wieku
berkut
whirlwind имел в виду что большая часть приложения у горе программиста завязана на каком-нибдуь реестре-синглтоне. Это ведь тоже самое что использовать глобалы. Те же яйца только сбоку. В результате приложение поулчается ужасно неповоротливым. Хотя до конца насчет "статика -- зло" согласиться не могу.

-~{}~ 21.03.08 21:43:

Alexandre
$db = DB::getInstance();
$sess = SESSIONS::getInstance();
ну ведь ты же это делаешь где-ниубудь в методе, правильно? а если бы ты передал оба объекта через аргументы, уже гибче получилось получилось бы. А если бы ты еще передал через аргумент один единственный тулкит, в котором были бы все самые нужные объекты, то еще лучше...
 

korchasa

LIMB infected
Автор оригинала: Alexandre
чем плохо:
$db = DB::getInstance();
$sess = SESSIONS::getInstance();
какая может быть зависимость, если у нас два разных класса: DB и SESSIONS?
А если у нас два соединения с базой? ;)
 

master_x

Pitavale XXI wieku
berkut
весомый агумент
меня не разведешь =)
А если серъезно. Когда вы получаете свои сессии и коннекты описанным Alexandre способом, вы прям там, в своем методе, зашиваете зависимость на конкретные классы.
 

Alexandre

PHPПенсионер
ну ведь ты же это делаешь где-ниубудь в методе, правильно? а если бы ты передал оба объекта через аргументы, уже гибче получилось получилось бы. А если бы ты еще передал через аргумент один единственный тулкит, в котором были бы все самые нужные объекты, то еще лучше...
если это один раз, на худой случай пять, то может быть и лучше.
А когда у тебя есть 10 классов вложенностью порядка несколько больше 3-х, то раздувать кол-во параметров в конструкторе или реализовать отдельным методе типа setDB( $db) & setSess($ses) и тянуть кучу переменных и одинаковых свойств не всегда есть красивое решение. Пусть даже будет тоолкит setBasePropertyes( $props ). Это я должен тянуть на все уровни вложенности из-за какого-то класса БД или сессии. У меня и без этого куча параметров, которые надо в голове держать.

-~{}~ 21.03.08 23:33:

А если у нас два соединения с базой?
а вот если два соединения с базой, то тут другой подход,
делаем стек (array) на базе синглетона.
на каждый db->open в стек заносим коннекцию, а счетчик стека увеличиваем на 1, уменьшаем при закрытии.

для каждого метода пишем обертку,
это выглядит приблизительно так:
PHP:
$db->open(....); // дефолтная коннекция
$cn1 = $db->open(....); // коннекция 1
$cn2 = $db->open(....); // коннекция 2


$db->query( $query, $cn1 ); // для коннекции 1
$db->query( $query  ); // дефолтно для 0 (первая коннеция)
$db->query( $query , $cn2 ); // для коннекции 2
$cn1 и $cn2 представляют счетчики коннекция
при том, нам все равно, с какой БД бвла коннекция, дефолтная мб с муськой, а первая с постгресом, а вторая с sqlLite

-~{}~ 21.03.08 23:38:

А если серъезно. Когда вы получаете свои сессии и коннекты описанным Alexandre способом, вы прям там, в своем методе, зашиваете зависимость на конкретные классы.
а так, если тяну туулкит через пять классов - я не получаю зависимость?
 

master_x

Pitavale XXI wieku
Alexandre
вот к примеру придется тебе SESSIONS по какой-то причине переименовать на ADVANCED_SESSIONS и тебе придется переписать все места получения этого объекта... у меня я всего лишь перепишу место регистрации сервиса:
PHP:
PSR_Services::getInstance()->register('session', new SESSIONS); //было
PSR_Services::getInstance()->register('session', new ADVANCED_SESSIONS); //стало
а теперь пример использования сервисов:
PHP:
public function servicesUsageExample($services){
   list($session, $logger)=$services->find('session', 'logger');
   ...
}
в примере нигде ничто не завязано на конкретные классы
 

berkut

Новичок
Когда вы получаете свои сессии и коннекты описанным Alexandre способом, вы прям там, в своем методе, зашиваете зависимость на конкретные классы
а если таскать какой-то тулкит, то какая разница? на примере можно?
 
Сверху