Magento 2:创建具有不可变状态的数据对象?


9

整理另一个Magento 2中的评论

如果需要共享一些计算值,则将计算行为放在单独的对象中,并从需要该值的块中调用它。不建议使用注册表,因为它是全局可变状态,您永远不确定从那里会得到什么。

有没有办法在Magento 2中创建具有不变状态的对象?不建议使用注册表(Magento\Framework\Registry),因为它是全局可变的状态(大概是因为,尽管该register方法不允许您更改现有密钥,但是您可以取消设置然后重置该密钥)。

但是,Magento 2中的任何对象都存在相同的问题。如果要创建对象

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

class ViewVars extends DataObject
{
}

然后,自动构造函数依赖项注入可确保任何人都可以抓住该共享库。如果对象是未共享的,则视图/块无法抓取它。

从理论上讲,我们可以做类似的事情

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;
    }
}

但是,与为视图设置单个变量一样,这似乎是一项任务的很多工作。Magento 2中有更好的方法来创建我不知道的不可变数据对象吗?


旧的Mage Registry模式不会尝试使值不变吗?恕我直言,这应该是一个lang构造。M2与HHVM兼容,因此,如果您迫切需要此结构,则可以采用Hack,它提供了不变的数据类型。显然,这是在开玩笑中说的,而且我的头翘在了一边,仿佛要示意这实际上是一件可以做的事情。
philwinkle

1
我认为Anton的评论的重点在于,如果您使用注册表界面,则不能保证您实际获得的是什么。您可以说,“好吧,我将\ My \ Model存储在此处的注册表项current_model中,并根据需要使用它”。但是(1)不能保证current_model是\ My \ Model的实例(或任何东西);(2)执行路径中其他任何地方的任何代码都可以以任何方式使用或修改该注册表项。这可能会导致大问题。最好使用定义的接口和具有依赖项注入的单例来维护该状态数据。
Ryan Hoerr 2015年

带setter的对象不是一成不变的。使用构造函数在对象中设置数据。
康迪(Kandy)2015年

Answers:


4

不,目前在Magento 2中没有更好的方法来创建不可变数据对象。您可以创建它,例如通过从接口生成生成器和构造函数。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.