Magento 2: ¿Crear objetos de datos con estado inmutable?

9

Combinando un comentario en otro Magento 2

Si necesita compartir algún valor calculado, coloque el comportamiento de cálculo para separar el objeto y llamarlo desde los bloques que requieren ese valor. Se desaconseja el registro porque es un estado global mutable y nunca está seguro de lo que obtendrá de allí.

¿Hay alguna manera de crear un Objeto en Magento 2 con estado inmutable? Magento\Framework\RegistrySe desaconseja el uso del registro ( ) porque es un estado mutable global (presumiblemente porque, aunque el registermétodo no le permite cambiar una clave existente, puede desarmarla y luego restablecerla).

Sin embargo, el mismo problema existe para cualquier objeto en Magento 2. Si tuviera que crear un objeto

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

class ViewVars extends DataObject
{
}

Luego, la inyección automática de dependencia del constructor asegura que cualquiera pueda agarrar ese objeto compartido. Si el objeto no se comparte, la vista / bloque no puede tomarlo.

En teoría, podríamos hacer 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;
    }
}

Pero eso parece mucho trabajo para una tarea tan común como establecer variables individuales para una vista . ¿Hay una mejor manera en Magento 2 para crear objetos de datos inmutables que desconozco?

Alan Storm
fuente
¿No intenta el antiguo patrón del Registro de Magos hacer que el valor sea inmutable? En mi humilde opinión esto debería ser una construcción lang. M2 es compatible con HHVM, por lo que si necesita desesperadamente esta construcción, podría adoptar Hack, que proporciona tipos de datos inmutables. Obviamente, esto se dice tanto en broma como con la cabeza ladeada hacia un lado como para indicar que esto en realidad puede ser una Cosa que uno podría hacer ™.
philwinkle
1
Creo que el punto del comentario de Anton fue más que si estás usando una interfaz de registro, no hay garantía sobre lo que realmente estás sacando. Puede decir, 'está bien, voy a almacenar \ My \ Model en la clave de registro current_model aquí, y usarlo según sea necesario'. Pero (1) nada garantiza que current_model sea una instancia de \ My \ Model (o cualquier cosa); y (2) cualquier código en cualquier otro lugar de la ruta de ejecución podría usar o modificar esa clave de registro de cualquier manera. Eso podría causar grandes problemas. Es mejor usar una interfaz definida y un singleton con inyección de dependencia para mantener esos datos de estado.
Ryan Hoerr
El objeto con setters no es inmutable. Use el constructor para establecer datos en el objeto.
KAndy

Respuestas:

4

No, actualmente no hay una mejor manera en Magento 2 para crear objetos de datos inmutables. Puede crearlo, por ejemplo, mediante captadores de generación y constructor desde la interfaz.

Kandy
fuente