Doctrine 2 中的不可变集合?

Posted

技术标签:

【中文标题】Doctrine 2 中的不可变集合?【英文标题】:Immutable collections in Doctrine 2? 【发布时间】:2011-09-10 23:22:55 【问题描述】:

我正在寻找一种从 Doctrine 2 中的域对象返回不可变集合的方法。让我们从 doc 中的这个示例开始:

class User

    // ...

    public function getGroups()
    
        return $this->groups;
    


// ...
$user = new User();
$user->getGroups()->add($group);

从DDD 的角度来看,如果User 是聚合根,那么我们更愿意:

$user = new User();
$user->addGroup($group);

但是,如果我们确实也需要 getGroups() 方法,那么理想情况下我们不希望返回对集合的内部引用,因为这可能会让某人绕过 addGroup() 方法。

除了创建自定义的不可变集合代理之外,是否有返回不可变集合的内置方法?比如……

    public function getGroups()
    
        return new ImmutableCollection($this->groups);
    

【问题讨论】:

【参考方案1】:

最简单(也是推荐)的方法是toArray():

return $this->groups->toArray();

【讨论】:

【参考方案2】:

我想最简单的方法是使用iterator_to_array

iterator_to_array 将可迭代对象转换为数组,因此无需直接返回集合,您只需执行return iterator_to_array($this->foo);

这还有一个额外的好处,就是可以在返回的列表上使用像 array_map 这样的函数,因为它们不适用于类似数组的对象。

【讨论】:

确实是优秀的解决方案。谢谢! 刚刚注意到return $this->groups->toArray(); 产生了相同的结果! 如果您想保留 ArrayCollection 功能,也可以使用return new ArrayCollection($this->groups->toArray());

以上是关于Doctrine 2 中的不可变集合?的主要内容,如果未能解决你的问题,请参考以下文章

Java中的不可变数组

ReadOnlyCollection vs Liskov - 如何正确建模可变集合的不可变表示

.NET不可变集合已经正式发布

对于更新不依赖于先前值的不可变集合,是不是有任何理由更喜欢 Interlocked 而不是 volatile?

当我们创建空的不可变列表/集合/映射时,是否有任何实际的应用程序/用例

java中的不可变类