webdevilopers / php-ddd

PHP Symfony Doctrine Domain-driven Design
201 stars 10 forks source link

Doctrine (Array)Collection and other equivalents to Java (Array)List #20

Open webdevilopers opened 7 years ago

webdevilopers commented 7 years ago

When reading my first DDD Java examples I saw a lot of Lists:

class Order
{
    private Integer ID;
    private Customer owner;
    private List<Product> ordered;

A List is an interface like Set and has ArrayList as stated by @iamzero

Unfortunately PHP does not have a true equivalent as @giorgiosironi knows:

But we have @doctrine Collections:

And alternatives like Ardent by @morrisonlevi:

The docs say:

An ordered collection (also known as a sequence). The user of this interface has precise control over where in the list each element is inserted. The user can access elements by their integer index (position in the list), and search for elements in the list.

When using @doctrine ArrayCollections you can use the indexBy mapping to make your Collection indexed (ordered):

Doctrine 2 collections are modelled after PHPs native arrays. PHP arrays are an ordered hashmap, but in the first version of Doctrine keys retrieved from the database were always numerical unless INDEX BY was used. You have to manage both the key and field if you want to change the index by field value.

But you have to be careful when using accessors as @MacDada warns:

Still it seems to be a matter of taste if you use ArrayCollection at all in your Domain Models:

Don't be alarmed by the use of ArrayCollections. Notice that is in the Doctrine/Common namespace. It's just a little utility array wrapper with no particular ties to the Doctrine persistence layer. You could easily replace it with another array class.

@tPl0ch warns:

The problem with Doctrine collections and the ORM is that you cannot use custom Collection implementations since you will always receive a PersistenCollection in your proxies.

What are your thoughts? Any use cases? Any comparison to the Java DDD approaches using List?

webdevilopers commented 7 years ago

I also recognized @yvoyer using the term Collection for InMemory Repositories:

If someone used Doctrine (ArrayCollections) throughout his project it could be used as a PHP wrapper - analog to the Java (Array)List) - and return it (like Doctrine Repositories do using default hydration):

final class OwnerCollection implements OwnerRepository, \Countable
{
    /**
     * @var ArrayCollection Owner[]
     */
    private $owners = [];

    /**
     * @param OwnerId $ownerId
     *
     * @throws EntityNotFoundException
     * @return Owner
     */
    public function ownerWithId(OwnerId $ownerId)
    {
        if (! isset($this->owners[$ownerId->id()])) {
            throw EntityNotFoundException::entityWithIdentity($ownerId);
        }
        return $this->owners[$ownerId->id()];
    }

Analog to Java:

public List<Order> findAllMatching(Criteria someCriteria)
{
    ResultSet rcds = this.db.execFindOrdersQueryWith(someCriteria.toString());
    List<List<String>> results = convertToStringList(rcds);

    List<Order> returnList = new ArrayList<Order>();

    for(List<String> row : results)
        returnList.add(this.orderFactory.createFrom(row));

    return returnList;
}