Вопрос по ООП синтаксис

AmdY

Пью пиво
Команда форума
Естественно говнокод. Фасад - это синглтон, в котором логика вынесена в отдельный класс-сервис, а пользуются этим сервисом исключительно через глобальный объект, фасад, синглтон то есть.
Вы якобы можете использовать сервис по человечески, но на практике никто этого не делает. Иллюзия чистого кода.
Эм... при чём здесь синглетон, это фасад для IOC, вместо IoC::get('Foo')->bar() или $this->app->make('Foo')->bar() используется человекопонятная запись Foo::bar(), при этом на этапе тестирования из коробки имеется возможность мокать Foo::shouldReceive('bar');
На качество кода это никак не влияет, нет отличий от SF или других с их $this->get('doctrine.orm.entity_manager');

Да и пользоваться фасадами никто не заставляет. Говнокод у laravel внутри, покопайся в компонентах. Особенно бесит корявая перегрузка error_hanlder в 5-й версии, когда фреймворк валится даже в дев режиме с пустой страницей без строчки в логах.
 

флоппик

promotor fidei
Команда форума
Партнер клуба
Особенно бесит корявая перегрузка error_hanlder в 5-й версии, когда фреймворк валится даже в дев режиме с пустой страницей без строчки в логах.
Там пакетик старый whoops можно вернуть, кстати, будет поведение как в 4ке.
 

Absinthe

жожо
Эм... при чём здесь синглетон, это фасад для IOC
Это очень свободная интерпретация фасада.
И если подходить к этим паттернам дотошно и буквально, то на синглтон ларавеловские фасады похоже больше, чем на фасад.

На качество кода это никак не влияет, нет отличий от SF или других с их $this->get('doctrine.orm.entity_manager');
В symfony мире за $this->getContainer()->get() по рукам бьют.
 

MiksIr

miksir@home:~$
то на синглтон ларавеловские фасады похоже больше, чем на фасад.
Что-то ты сейчас странное сказал. Синглтон - это способ создания и доставки объекта до потребителей, а фасад - что делает этот объект. Если дотошно и буквально.
 

Absinthe

жожо
Что-то ты сейчас странное сказал. Синглтон - это способ создания и доставки объекта до потребителей, а фасад - что делает этот объект. Если дотошно и буквально.
А теперь открой проект на ларавел, поставь брекпоинт на "фасад" и посмотри, что он делает ;)
Создает и доставляет объект.

А теперь читаем, что делает настоящий фасад: https://en.wikipedia.org/wiki/Facade_pattern
A facade is an object that provides a simplified interface to a larger body of code, such as a class library.
Я не вижу, как ларавеловский "фасад" предоставляет новый интерфейс к какой-то библиотеке. Тут дословный меппинг с теми же методами, а не новый упрощенный интерфейс.
 

MiksIr

miksir@home:~$
Не, синглтон создает и доставляет _себя_. Так что уже тупой маппинг - это уже выходит за рамки синглтона. Оно может не быть фасадом, а быть, допустим, прокси, если интерфейсы одинаковые. Но это по хорошему накладывает обязательство на реализацию всего интерфейса. Тогда может быть адаптером.

А в ларавеле это зовется фасадом, как я понимаю, ибо это заготовка для фасадов. А то, что некоторые классы фреймворка, реализующие эту заготовку, не достаточно сложны, что бы проявилось "упрощение интерфейса"... ну что уж тут делать.
 

Absinthe

жожо
Не, синглтон создает и доставляет _себя_.
Нет, это всего лишь самый популярный способ реализации.
The singleton pattern is a design pattern that restricts the instantiation of a class to one object.

А в ларавеле это зовется фасадом, как я понимаю, ибо это заготовка для фасадов. А то, что некоторые классы фреймворка, реализующие эту заготовку, не достаточно сложны, что бы проявилось "упрощение интерфейса"... ну что уж тут делать.
В ларавеле фасад всегда представлен меппингом один-к-одному для всех наследников \Illuminate\Support\Facades\Facade
 

hell0w0rd

Продвинутый новичок
Эм... при чём здесь синглетон, это фасад для IOC, вместо IoC::get('Foo')->bar() или $this->app->make('Foo')->bar() используется человекопонятная запись Foo::bar(), при этом на этапе тестирования из коробки имеется возможность мокать Foo::shouldReceive('bar');
На качество кода это никак не влияет, нет отличий от SF или других с их $this->get('doctrine.orm.entity_manager');

Да и пользоваться фасадами никто не заставляет. Говнокод у laravel внутри, покопайся в компонентах. Особенно бесит корявая перегрузка error_hanlder в 5-й версии, когда фреймворк валится даже в дев режиме с пустой страницей без строчки в логах.
Я же говорю, ты живешь в иллююзии :) Синглтон отличается от ваших фасадов, только кол-вом классов.
В Symfony ты должен отдельно описать зависимости и они внедряются в конструктор.
https://github.com/laravel/framework/blob/5.0/src/Illuminate/Support/Facades/Facade.php - вот сюда загляните, наконец.
PS
Я кстати не против laravel. Просто я понял что либо пишем с кусками говнокода (но надо осознавать, что конкретно это - не правильно), либо пишем красиво, соблюдая всевозможные принципы - но это муторно.
Ну то есть серьезно, описать logger как зависимость гораздо дольше, чем незадумываясь вызвать Logger::log и не париться.
PPS
А в симфони есть еще отличный бандл (JMSDiExtraBundle)
PHP:
/**
* @Inject("doctrine")
*/
public $doctrine;
 
Последнее редактирование:

MiksIr

miksir@home:~$
Нет, это всего лишь самый популярный способ реализации.
Возможно. А ты знаешь другие способы _гарантировать_ существование только одного экземпляра?
Но даже если не себя - ключевое - создает и предоставляет доступ.
А предоставление доступа посредством проксирующих методов - это адаптер или прокси или фасад - в общем структурные паттерны, а не порождающие, как синглтон.
 

hell0w0rd

Продвинутый новичок
MiksIr, DI другой способ.
PHP:
User::find() // плохо
$this->get('User')->find()  // плохо
function($user) {
$user->find() // хорошо
}
 

MiksIr

miksir@home:~$
Вот static::resolveFacadeInstance - это синглтон, а __callStatic - это прокси.
Фасадом, тут, конечно, и не пахнет, но, ничего не мешает в своей релизации добавлять методы, выходящие за рамки тупого проксирования. Может это и имелось в виду.

@hell0w0rd, DI обеспечивает единственность лишь при работе с DI. Это "синглтон", но не "Синглтон" ;) У последнего достаточно фиксированная схема.
 

cDLEON

Онанист РНРСlub
Я же говорю, ты живешь в иллююзии :) Синглтон отличается от ваших фасадов, только кол-вом классов.
В Symfony ты должен отдельно описать зависимости и они внедряются в конструктор.
https://github.com/laravel/framework/blob/5.0/src/Illuminate/Support/Facades/Facade.php - вот сюда загляните, наконец.
PS
Я кстати не против laravel. Просто я понял что либо пишем с кусками говнокода (но надо осознавать, что конкретно это - не правильно), либо пишем красиво, соблюдая всевозможные принципы - но это муторно.
Ну то есть серьезно, описать logger как зависимость гораздо дольше, чем незадумываясь вызвать Logger::log и не париться.
PPS
А в симфони есть еще отличный бандл (JMSDiExtraBundle)
PHP:
/**
* @Inject("doctrine")
*/
public $doctrine;
Ни когда не понимал желания ПХП программистов натянуть презерватив на забор. Комментарии для комментариев. Не хватает возможностей языка - иди в Python или Java. Там декораторы есть из коробки.
 

Вурдалак

Продвинутый новичок
Ваши «фасады» можно свободно называть «singleton-like сущностями». Беспрепятственный глобальный доступ к инстансу, отсутствие изолированности, неявные зависимости — эти проблемы никуда не деваются. В противном случае можно спокойно пользоваться и «классическими» singleton'ами вида
PHP:
class Foo extends Singleton
{
    // ...
}
— ну а что, вводишь FooInterface и делай реализацию для DI. В конструктор singleton'а (первый вызов), можно зафигачить инстанс FooInterface поведение объекта тоже глобально изменится.
 

hell0w0rd

Продвинутый новичок
fixxxer, тем что объект конфигурируется извне, а не самостоятельно. Далее в тестах, или где еще нужно ты мокаешь Doctrine и напрямую суешь в конструктор/свойство.
Пример из доков. Я просто самый короткий выше написал.
PHP:
/**
* @DI\InjectParams({
*    "em" = @DI\Inject("doctrine.orm.entity_manager"),
*    "session" = @DI\Inject("session")
* })
*/
public function __construct($em, $session)
{
    $this->em = $em;
    $this->session = $session;
}
 

fixxxer

К.О.
Партнер клуба
Мне кажется сомнительным, что @Inject("doctrine") в данном случае находится "извне". (Впрочем, ровно как и в самой доктрине мне кажется сомнительным, что phpdoc-маппинг находится как бы не в entity.)

Инъекция в свойства, впрочем, мне тоже не нравится.
 

hell0w0rd

Продвинутый новичок
fixxxer, инъекция свойства не обязательна, в общем читай выше. Подход с аннотациями стоит использовать в контроллерах. Собственно они только там вроде и работают. Сервисы правильнее конфигурировать через yml-файл.
 

hell0w0rd

Продвинутый новичок
cDLEON, тут чуть ли не все интересные топики на форуме из набрасывания на вентилятор состоят :) Я последнее время на JS больше пишу, es6 много крутых возможностей дал вместе с flow от FB.
 

fixxxer

К.О.
Партнер клуба
В контроллере сойдет, да. Но как по мне, что уж там в контроллере это вообще несущественно, хоть и через container->get в конструкторе, контроллер это ж такая фигня.
 

Absinthe

жожо
Возможно. А ты знаешь другие способы _гарантировать_ существование только одного экземпляра?
Знаю, например использование непубличных классов в пакете.
Если считать, что пользователь не будет нарушать базовых принципов работы с фреймворком, то таких способов уже много, а если нарушит, то прекрасно понимает для чего.
Т.е. фасады Ларавел - это мягкое ограничение, которое технически можно обойти, но для этого придется применять осознанные действия.
Но и классический синглтон можно обойти метапрограммированием в языках, которые его поддерживают.


MiksIr, DI другой способ.
PHP:
User::find() // плохо
$this->get('User')->find()  // плохо
function($user) {
$user->find() // хорошо
}
Ты тип забыл передать.

Мне кажется сомнительным, что @Inject("doctrine") в данном случае находится "извне".
Это сильная связанность, прямая зависимость. Это SL, а не DI.
 
Сверху