No Magento 2 há diversas funcionalidades que foram implementadas visando a melhoria da performance do software. Hoje falaremos sobre isso Magento 2 Proxy.
Vamos analisar o script abaixo:
class SlowLoading { public function __construct() { // ... Do something resource intensive } public function getValue() { return 'SlowLoading value'; } } class FastLoading { protected $slowLoading; public function __construct( SlowLoading $slowLoading ){ $this->slowLoading = slowLoading; } public function getFastValue() { return 'FastLoading value'; } public function getSlowValue() { return $this->slowLoading->getValue(); } }
Nós temos a classe SlowLoading (sendo uma classe pesada) em que foi injetada na classe FastLoading via construtor. Ao executarmos a classe FastLoading, mesmo que não seja chamado nenhum método da classe SlowLoading, a classe FastLoading fará o carregamento da SlowLoading, onerando o seu carregamento. E isso é bastante prejudicial para o nosso software.
Magento 2 Proxy
O Magento 2 traz uma solução muita boa para acabar com o problema que relatamos acima: Proxy. O Proxy é uma versão “preguiçosa” da classe que ele está estendendo. Fazendo com que ela seja executada, apenas quando algum método dele for executado.
Voltando ao nosso módulo, vamos a um exemplo:
<?php namespace ForMage\Learning\Model; class SlowLoading { public function __construct() { echo "The SlowLoading class was loaded"."<br/>"; } public function getValue() { return 'SlowLoading value'; } }
Criamos a nossa classe SlowLoading, como vemos no script acima.
<?php namespace ForMage\Learning\Controller\Page; use Magento\Framework\App\Action\Context; use Magento\Framework\App\ResponseInterface; use ForMage\Learning\Api\SizeInterface; use ForMage\Learning\Api\ColorInterface; use ForMage\Learning\Model\Product\Shoe; use ForMage\Learning\Model\Product\Shirt; use Magento\Framework\Event\ManagerInterface; use ForMage\Learning\Model\SlowLoading; class Index extends \Magento\Framework\App\Action\Action { protected $size; protected $color; protected $product; protected $shirt; protected $eventManager; protected $slowLoading; public function __construct( Context $context, SizeInterface $size, ColorInterface $color, Shoe $product, Shirt $shirt, ManagerInterface $eventManager, SlowLoading $slowLoading ) { parent::__construct($context); $this->size = $size; $this->color = $color; $this->product = $product; $this->shirt = $shirt; $this->eventManager = $eventManager; $this->slowLoading = $slowLoading; } public function execute() { $id = $this->getRequest()->getParam('id', 0); if ($id) { echo $this->slowLoading->getValue(); } else { echo "SlowLoading was not loaded"; } } }
Em nosso Controller, adicionamos a nossa classe SlowLoading no seu construtor e, no seu método execute temos o seguinte tratamento:
public function execute() { $id = $this->getRequest()->getParam('id', 0); if ($id) { echo $this->slowLoading->getValue(); } else { echo "SlowLoading was not loaded"; } }
Ou seja, o método getValue()
da classe SlowLoading só será executado se houver um parâmetro ID na nossa rota. Ao acessar a rota sem qualquer parâmetro temos o seguinte resultado:
Veja que o nosso tratamento funcionou, não carregando o método getValue()
, porém houve o carregamento da nossa classe SlowLoading. Mesmo não sendo de fato usada, ela está sendo carregada e onerando o carregamento da nossa página.
Para resolver isso, vamos ao nosso di.xml, e efetuamos a seguinte alteração:
<arguments> <argument name="slowLoading" xsi:type="object">ForMage\Learning\Model\SlowLoading\Proxy</argument> </arguments>
Ao fazermos isso, falamos para o Magento 2 que a deverá ser criado um Proxy para a classe SlowLoading. Feito essa alteração, após recompilar vemos o seguinte:
O Magento 2 gerou uma classe Proxy para a nossa classe SlowLoading. Agora, ao acessar a nossa rota sem passar o parâmetro ID temos o seguinte resultado:
Ou seja, devido a nossa validação, a classe SlowLoading não foi carregada. Mas, acessando a rota passando um parâmetro ?id=10, por exemplo, temos o seguinte resultado:
Como a nossa validação retornou um true a nossa classe SlowLoading foi executada.
A utilização de Proxy é muito importante no desenvolvimento de um módulo em Magento 2. Sempre que possível, considere a utilização de Proxies.
Dúvidas? Posta aí!
Um abraço!