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

Ярослав

Новичок
whirlwind
<<Наглядный пример чего?
Что static зло :)

Хотя прочитав топик меня так и не убедили

-~{}~ 21.03.08 22:51:

вот к примеру придется тебе SESSIONS по какой-то причине переименовать на ADVANCED_SESSIONS
Зачем?
Такие вещи если уж делаешь то по-моему в переименовании они не нуждаются
 

master_x

Pitavale XXI wieku
Ярослав
ну сказал же "к примеру" =)

-~{}~ 22.03.08 00:11:

triumvirat
по теме:
статический метод является методом класса.
ты дампишь объект, следовательно получаешь методы объекта, не больше.
хотя в последней версии пхп из-за late static binding все перевернулось с ног на голову.
 

Sluggard

Новичок
master_x
Когда вы получаете свои сессии и коннекты описанным Alexandre способом, вы прям там, в своем методе, зашиваете зависимость на конкретные классы.
Он написал две строчки. Куда их засунуть - это уже у кого на что ума хватит. Используй интерфейcные классы или фабрики. В чем вопрос?
Разве? Здесь же все предельно просто. Статика - зло, потому что мы так пишем свои программы. Может и было бы иначе, но это же надо думать, как пишут горе-программисты, чтобы статика не была злом.
большая часть приложения у горе программиста завязана на каком-нибдуь реестре-синглтоне
Да куда же ему тягаться до твоего Чуда-Юда-ПСР-Сервиса? :) Это же уже не какие-то яйца...
Тебя не напрягает постоянно таскать в параметрах $services? Или ты искренне веришь, что сменишь супер PSR_Services на что-то сверх-идеальное? И как я понимаю, у тебя нет конструкций типа:
PHP:
$news = new news();
исключително:
PHP:
$factory = $services->find('factory');
$news = $factory->create('news');
 

IIIEPJIOK

Новичок
ну сказал же "к примеру" =)
Да, трындец, к какому примеру, тяжелая неделя что ли выдалась?
Переименовать класс это последнее что может придти в голову, свихнувшемуся от скуки программисту. Это ж как тип данных переименовать.

new Foo;
Foo::$a;
Foo::b();

Мы ожидаем, что во-первых есть объявленный класс Foo, во-вторых у класса Foo есть статическое свойство $a, и метод $b. Нам уже сложнее переименовать этот класс, т.к. на него могут быть завязаны клиенты.
АбАлДеть

е если мы пишем:
$foo = new Foo;
$foo->$a;
$foo->b();

мы конечно же не ожидаем, что во-первых есть объявленный класс Foo, во-вторых у класса Foo есть свойство $a, и метод $b.
Я Правильно понял? :))))))))))

-~{}~ 22.03.08 01:08:

Статика - зло, потому что мы так пишем свои программы
Вот он - луч света в темном царстве!!!! +1
 

Sluggard

Новичок
public function servicesUsageExample($services){
list($session, $logger)=$services->find('session', 'logger');
...
}

в примере нигде ничто не завязано на конкретные классы
Совсем непригодный код. Смотри сам. Вот придется тебе, по какой-либо причине, метод find переименовать на get. И будешь ты переписывать все места, где вызывается этот метод... А потом захочешь переименовать все методы класса ADVANCED_SESSIONS. И снова везде все переписывать... Может вызывать методы класса через ПСР-Сервис? Помни, что может захотется переименовать все свойства класса. Позаботься хотя бы о public и protected. Ну и что константы вдруг захочешь переименовать - тоже не забудь.
 

fixxxer

К.О.
Партнер клуба
:)
а если серьезно, то я не совсем втыкаю, чем registry singleton с перегруженным get и "защищенным" set хуже таскания вокруг хэндла на $application (или там $application->something).
 

fixxxer

К.О.
Партнер клуба
ну, по крайней мере для меня
1) инкапсуляция (защита доступа)
2) возможность lazy load
3) незасорение глобального пространства (ну, на это как бы и пофиг, но до кучи)
 

master_x

Pitavale XXI wieku
Sluggard
ты реально не в теме. и поэтому утрируешь.
И как я понимаю, у тебя нет конструкций типа:

$news = new news();

исключително:

$factory = $services->find('factory');
$news = $factory->create('news');
ты вот тут прикидываешься или как?
ты видишь разницу между простым объектом, который живет в пределах одного метода (в твоем случае news) и умирает по окончании этого метода и объекта, который будет постоянно нужен всеми и вся в пределах ВСЕГО твоего ОГРОМНОГО приложения? или ты реально прикидываешься? про непригодный код, ты конечно ляпнул =) вещь работает и расширяется коммандой проггеров постоянно и никто не жалуется. методы никто переименовывать не собирается... есть интерфейсы, которым следуем. а про переименовывание класса это был, мля, ПРИМЕР. простой пример, чтоб дошло. теперь понятно?
в общем для чего мне нужны сервисы по пунктам уже написал fixxer
 

master_x

Pitavale XXI wieku
Лан вот тебе последний, легкий пример, может осилишь:
PHP:
class Person {
    public function create($mapper, $input, $services){
        list($http, $logger)=$services->find('http', 'logger');
        if($input->valid()){
            $mapper->save($input);
            $logger->write('Persons data succesfully saved');
            $http->redirect(Person::SAVED_PAGE);
    }
}
вот пришел проггер, понравился ему этот класс и его функционал. единственное что он захотел изменить это способ записи в лог и редирект. поэтому он берет и пишет свои классы по существующим интерфейсам. далее с небывалой легкостью отделяет весь класс Person с его методами от существующего приложения и использует его как ему угодно, потому как прямых зависимостей тут не наблюдается.
а вот примерно как было бы у тебя:
PHP:
class Person {
    public function create($mapper, $input){
        $http=HTTP_TOOLS::getInstance();
        $logger=SUPPA_LOGGER::getInstance();
        if($input->valid()){
            $mapper->save($input);
            $logger->write('Persons data succesfully saved');
            $http->redirect(Person::SAVED_PAGE);
    }
}
вот теперь попробуй без переопределения метода create заставь его работать с другим логгером. у тебя один единственный метод тянет уже два класса за собой без необходимости.
 

HraKK

Мудак
Команда форума
Ржу шота.
list($http, $logger)=$services->find('http', 'logger');
Тут он получается для использования другого логера в тулките определит другой класс. И при этом упадет весь проект :))) Потому что другие то классы ничего не подозревая используют старый нужный им с большой вероятностью с другим интерфейсом( не в этом случае но вполнееее реальный)

Тогда выход будет только один переписать на
list($http, $logger)=$services->find('http', 'logger_advanced');
тогда извините, а чем это отличается от
$logger=SUPPA_LOGGER::getInstance();
?
И еще это ты определил когда на весь проект глобалкастингом ты заменишь одну тулзу на другую. А если мне надо локально? Опять переписывать метод. А глобал кастингом я свободно и в синлетоне подменю класс. например классом
class logger extend suppa_logger
{
}
 

master_x

Pitavale XXI wieku
HraKK
Потому что другие то классы ничего не подозревая используют старый нужный им с большой вероятностью с другим интерфейсом
читать умеешь?
вот пришел проггер, понравился ему этот класс и его функционал. единственное что он захотел изменить это способ записи в лог и редирект. поэтому он берет и пишет свои классы по существующим интерфейсам
если тебе локально нужен другой логгер, возьми и перед вызовом своего локального кода, перерегистрируй сервис. все. опять же метод менять не надо.
class logger extend suppa_logger
{
}
вот про это кстати поподробнее. что ты там собирался подменять? у тебя в методе ссылка на SUPPA_LOGGER. ты можешь получить абсолютно другой логгер ( не трогая метод) только если ты:
а) перепишешь SUPPA_LOGGER (но ты же ведь взрослый мальчик и понимаешь что это глупо)
б) воспользуешься грязным хаком типа setInstance() в SUPPA_LOGGER.
Еще раз повторяю для всего есть интерейсы. Подменив один логгер на другой, ты ничего не сломаешь, до тех пор пока они оба написаны по одному интерфейсу.
 

rotoZOOM

ACM maniac
master_x То есть по твоему проблема в том, что если кто-то захочет прикрутить другой логгер, НО с тем же интерфейсом, то ему придется менять обращение к синглтону во всех модулях где он используется ? Но это ведь не так. Менять то придется только в 1 месте. В методе синглтона getInstance:
PHP:
class LOGGER
{
private static $instance = null; 

public static function getInstance()
    {
        if (null === self::$instance)
        {
            self::$instance = new SuppaLogger;
//            self::$instance = new Logger;
        }
        
        return self::$instance;
    }
};
И все. Во всем остальном коде как было LOGGER::getInstance так и останется.
Естественно, это справделиво только для классов реализующих одинаковые интерфейсы, но и в твоем случае это ограничение тоже накладывается.
Поправь меня, если я не прав.
 

HraKK

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

Sluggard

Новичок
master_x
про непригодный код, ты конечно ляпнул
Я исходил из твоей политики - все должно переименовываться изменением в двух местах.
вещь работает и расширяется коммандой проггеров
О да. Это показатель. Памятник поставь. Индусы тоже пишут код, который рвботает и расширяется командой индусов. Ровняйся на них.
единственное что он захотел изменить это способ записи в лог и редирект.
И потому мы не меняем реализацию одного метода, а пишем новый класс. А потом бегаем по всему проекту, меняя вызовы инстансов. Ты реально любишь делать лишнюю работу.
ты вот тут прикидываешься или как?
Угу. Меня твои примеры забавляют.
 

master_x

Pitavale XXI wieku
Sluggard
ты тролль. и судя по последнему сообщению ты до сих пор не в теме.

rotoZOOM
хорошо. поправляю. дело в том, что ты исправляя код класса LOGGER уже залезаешь в архитектуру приложения и делаешь его (приложение) еще более монолитным. об этом я уже писал. твое изменение распространится на все вызовы LOGGER::getInstance() а я могу поменять сервис прямо перед вызовом нужного мне метода, локально. и потом восстановить состояние реестра сервисов.
в общем я доказываю одну вещь: чем больше синглтонов (а следовательно и статических ссылок) в приложении тем больше зависимостей, тем неповоротливее становится приложение.
 

rotoZOOM

ACM maniac
master_x Я согласен с тобой, просто мысль таскать с собой в качестве аргумента services несколько коробит. Например такая ситуация: допустим существует такая вложенность объектов классов A -> B -> C (А в B, B в C). И допустим классу С нужны сервисы, B не нужны, A опять нужны. Получается, что хотя B и не нужны эти сервисы он все равно должен принимать их в качестве аргумента и передавать в A.
 

HraKK

Мудак
Команда форума
rotoZOOM
Ты не понял :)
services это синлетон - холдер. Поэтому таскать ничего не придется.

Еще раз повторю: никто не против тоолкитов

Просто не понятно чем он прпинципиально лучше например Registry или GLOBAL
Services::getInstance()->register(...)
Registry::set(...)
$GLOBAL[...]= new ....;
 

korchasa

LIMB infected
Автор оригинала: HraKK
...
Просто не понятно чем он прпинципиально лучше например Registry или GLOBAL
Services::getInstance()->register(...)
Registry::set(...)
$GLOBAL[...]= new ....;
Наличием единой точки входа, со всеми вытекающими, а так же возможностью выполнять разный функционал на разных вызовах.
 
Сверху