在DDD中,为什么不使用数组来存储实体集合?

时间:2013-01-15 21:11:47

标签: php domain-driven-design

我在所有DDD示例中都看到,集合是作为类实现的,例如在PHPMaster网站上:

<?php
namespace Model\Collection;
use Mapper\UserCollectionInterface,
    Model\UserInterface;

class UserCollection implements UserCollectionInterface
{
    protected $users = array();

    public function add(UserInterface $user) {
        $this->offsetSet($user);
    }

    public function remove(UserInterface $user) {
        $this->offsetUnset($user);
    }

    public function get($key) {
        return $this->offsetGet($key);
    }

    public function exists($key) {
        return $this->offsetExists($key);
    }

    public function clear() {
        $this->users = array();
    }

    public function toArray() {
        return $this->users;
    }

    public function count() {
        return count($this->users);
    }

    public function offsetSet($key, $value) {
        if (!$value instanceof UserInterface) {
            throw new \InvalidArgumentException(
                "Could not add the user to the collection.");
        }
        if (!isset($key)) {
            $this->users[] = $value;
        }
        else {
            $this->users[$key] = $value;
        }
    }

    public function offsetUnset($key) {
        if ($key instanceof UserInterface) {
            $this->users = array_filter($this->users,
                function ($v) use ($key) {
                    return $v !== $key;
                });
        }
        else if (isset($this->users[$key])) {
            unset($this->users[$key]);
        }
    }

    public function offsetGet($key) {
        if (isset($this->users[$key])) {
            return $this->users[$key];
        }
    }

    public function offsetExists($key) {
        return ($key instanceof UserInterface)
            ? array_search($key, $this->users)
            : isset($this->users[$key]);
    }

    public function getIterator() {
        return new \ArrayIterator($this->users);
    }
}

界面:

<?php
namespace Mapper;
use Model\UserInterface;

interface UserCollectionInterface extends \Countable, \ArrayAccess, \IteratorAggregate 
{
    public function add(UserInterface $user);
    public function remove(UserInterface $user);
    public function get($key);
    public function exists($key);
    public function clear();
    public function toArray();
}

为什么他们不使用简单的数组呢?使用给定的实现可以获得什么好处?

1 个答案:

答案 0 :(得分:1)

  

使用给定的实现可以获得哪些好处?

您可以轻松地为UserCollection添加其他行为,例如每当添加或删除新用户时都会做出反应(例如观察者模式)。使用数组时,必须将这些逻辑分散到各处,而使用类时,您可以将此逻辑放在一个位置并在那里控制它。它也更容易测试。

你还可以包含一些检查代码的不变量,确保UserCollection概念始终遵守域约束。

即使似乎没有立即需要约束或其他行为,这些可能会在项目生命的后期出现,并且在不是为可扩展性设计的代码库中实现它们会有些困难。