да, по сути в magento 2 это обычные middleware, подход мне нравится, хоть и довольно тяжелый в дебаге, например многими любимый guzzle использует такой подход без кодогенерации
кстати хороший пример composite это symfony form компонент, там как раз отдельный элемент формы и форма реализуют один интерфейс (методы setData, submit etc.)
Тоже заметил данную неточность. Еще по моему мнению пример декоратора также не верен, так как не показывает основное отличие декоратора и прокси, а именно добавление нового поведения/функционал к объекту. В примере показан обычный прокси. Классический пример декоратора div/table renderer для элементов формы имеет более «человеческое» лицо
Кстати, правильно ли я понимаю что судя по коду контейтера, после его отображения и запроса данных через XHR, компонент еще крутит индикатор загрузки? никак не боролись с задержкой транзишина на новый роут до подгрузки критичных данных? например redux-async-connect
код
if (!this.props.firstLoad) {
this.props.loadManagers(this.props.location);
}
В версии 6.0.1 так же поменялся способ подстановки мок-ответов. Теперь вместо EventSubscriber этим занимаются так называемые хендлеры.
Тест теперь выглядит вот так.
Тест
use GuzzleHttp\Client;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Psr7\Response;
use GuzzleHttp\Handler\MockHandler;
class APITest extends \PHPUnit_Framework_TestCase
{
/** @var API */
protected $api;
/** @var Client */
protected $client;
/** @var MockHandler */
protected $mockHandler;
protected function setUp()
{
$this->mockHandler = new MockHandler();
$this->client = new Client(['handler' => HandlerStack::create($this->mockHandler)]);
$this->api = new API($this->client);
}
protected function tearDown()
{
unset($this->api, $this->client, $this->mockHandler);
}
/**
* @dataProvider recentTransactionsDataProvider
*
* @param string $response
* @param int $expectedCount
*/
public function testGetRecentTransactions($response, $expectedCount)
{
$this->setUpExceptionAssertion($exception);
$this->mockHandler->append(new Response(200, [], $response));
$result = $this->api->getRecentTransactions();
$this->assertInternalType('array', $result);
$this->assertCount($expectedCount, $result);
}
}
Очень часто встречаю во всяких event disaptcher'ах регистрацию слушателей как [$this, 'methodName']
Так вот это работать и не будет в вашем примере. PHP 5.6.6
код
<?php
class a{
function b () {
echo 'b';
}
}
$a = new a();
[$a, 'b']();
В PHP использовал пару раз и пару раз видел в Doctrine2, но проверку типа на \Closure встречаю очень часто. В Scala приходилось использовать немного чаще. Но суть вопроса на понимание как устроены лямбды внутри.
Спасибо за статью! Сам часто задаю вопросы о callable на собеседовании. К сожалению многие спотыкаются если вопрос начать именно зачем ввели такой странный магический метод __invoke.
В вашем последнем примере есть неточность, как вы сами написали callable не всегда может быть вызвана через скобки, поэтому безопасно всегда использовать call_user_func
node.js — опциональная зависимость, без него все будет работать, модули будут грузиться on demand асинхронно.
У нас был выбор между портом r.js на java и собственно запускать r.js из родного node окружения. Мы приняли решение так как нам показалось, что сам r.js работает оптимальнее на node и шансов, что на сервере будет стоять node.js больше чем шансов найти там java
Спасибо за инструмент. Приятно видеть хороший код на PHP!
От себя хотел бы добавить, что использование таких компонентов как symfony/console облегчили бы вам жизнь и сделали код еще проще, а symfony/process позволили бы также решить проблемы запуска в различных ОС, для вычисления хеш сум думаю было бы удобнее использовать RecursiveDirectoryIterator.
Спасибо за статью. Мы используем в проекте Ratchet. Можете прокомментировать чем ваше решение отличается/лучше от уже устоявшейся, стабильной библиотеки?
Насколько я помню(говорил Joseph Rouff из SensioLabs на конфе слайды с доклада), то не обязательно создавать новый класс токена, ведь в симфони уже есть UsernamePasswordToken его можно переиспользовать