evodevo
evodevo

Reputation: 509

In DDD, why don't you use arrays to store collections of entities?

I've seen in all DDD examples, collections are implemented as classes, for example at PHPMaster website:

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

And the interface:

<?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();
}

Why don't they just use a simple array? What benefits do you get by using a given implementation?

Upvotes: 2

Views: 1676

Answers (1)

mantrid
mantrid

Reputation: 2840

What benefits do you get by using a given implementation?

you can easily augument UserCollection with additional behaviour, like reacting whenever a new user is added or removed (e.g. observer pattern). using arrays, one would have to scatter such logic all over the place, while using a class you can put this logic just in one place and control it there. it is also more testable.

you can also include some invariants checking code making sure UserCollection concept always adheres to domain constraints.

even if there seem to be no immediate need for constraints or additional behaviour, these may come up later in the project life and it would be somewhat difficult to implement them in code base that wasn't designed for extensibility.

Upvotes: 1

Related Questions