Magento 2: Criando objetos de dados com estado imutável?

9

Dovetailing fora um comentário em outro Magento 2

Se você precisar compartilhar algum valor calculado, coloque o comportamento de cálculo para separar um objeto e chame-o de blocos que requerem esse valor. O registro é desencorajado porque é um estado mutável global e você nunca sabe ao certo o que obterá a partir daí.

Existe uma maneira de criar um objeto no Magento 2 com estado imutável? O uso do registro ( Magento\Framework\Registry) é desencorajado porque é um estado mutável global (presumível porque, embora o registermétodo não permita alterar uma chave existente, você pode desabilitar e redefinir essa chave).

No entanto - o mesmo problema existe para qualquer objeto no Magento 2. Se eu fosse criar um objeto

namespace Pulsestorm\Helloworld\Model;
use Magento\Framework\DataObject;

class ViewVars extends DataObject
{
}

Em seguida, a injeção automática de dependência do construtor garante que qualquer pessoa possa pegar esse objeto compartilhado. Se o objeto não for compartilhado, a visualização / bloco não poderá agarrá-lo.

Em teoria, poderíamos fazer algo como

namespace Pulsestorm\Helloworld\Model;

class ViewVars
{
    protected $_data=false;
    protected function setData($data)
    {
        if($_data)
        {
            throw new Exception("Immutable");
        }
        $this->_data = $data;
    }

    public function getData()
    {
        return $this->_data;
    }
}

Mas isso parece muito trabalhoso para uma tarefa tão comum quanto definir variáveis ​​individuais para uma visualização . Existe uma maneira melhor no Magento 2 para criar objetos de dados imutáveis ​​dos quais não estou ciente?

Alan Storm
fonte
O antigo padrão do Mage Registry não tenta tornar o valor imutável? IMHO isso deve ser uma construção lang. M2 é compatível com HHVM, portanto, se você precisar desesperadamente dessa construção, poderá adotar o Hack, que fornece tipos de dados imutáveis. Obviamente, isso é dito em tom de brincadeira e com a cabeça inclinada para o lado, como se fosse um gesto de que isso pode realmente ser uma coisa que se poderia fazer.
philwinkle
11
Eu acho que o ponto do comentário de Anton foi mais do que se você estiver usando uma interface de registro, não há garantia sobre o que você realmente está divulgando. Você pode dizer: 'ok, vou armazenar \ My \ Model na chave do registro current_model aqui e usá-lo conforme necessário'. Mas (1) nada garante que current_model seja uma instância de \ My \ Model (ou qualquer outra coisa); e (2) qualquer código em qualquer outro lugar no caminho de execução pode usar ou modificar essa chave do Registro de qualquer maneira. Isso pode causar grandes problemas. Melhor usar uma interface definida e singleton com injeção de dependência para manter os dados desse estado.
Ryan Hoerr 10/09
Objetos com setters não são imutáveis. Use o construtor para definir dados no objeto.
Kandy

Respostas:

4

Não, atualmente não há maneira melhor no Magento 2 de criar objetos de dados imutáveis. Você pode criá-lo, por exemplo, por getters de geração e construtor a partir da interface.

KAndy
fonte