Collections
Collections provide type-safe containers for domain objects with functional programming operations.
Characteristics
- Type safety: Collections enforce element types at runtime
- Functional operations: map, filter, reduce, each
- Iterable: Works with foreach
- Countable: Supports
count()
Creating Typed Collections
Extend AbstractTypedCollection and specify the element type:
final class BooksCollection extends AbstractTypedCollection
{
protected function type(): string
{
return Book::class;
}
}
Usage
$books = new BooksCollection([$book1, $book2]);
// Access
$books->first(); // First element
$books->last(); // Last element
$books->count(); // Number of elements
// Functional operations
$titles = $books->map(fn (Book $book) => $book->getTitle()->getValue());
$available = $books->filter(fn (Book $book) => $book->getStatus()->isAvailable());
// Iteration
foreach ($books as $book) {
echo $book->getTitle()->getValue();
}
Creating Collections
// From array
$books = BooksCollection::fromArray([$book1, $book2]);
// From map (transform raw data)
$books = BooksCollection::fromMap($rows, fn (array $row) => new Book(/* ... */));
Repository Usage
Repositories return typed collections:
interface BookRepository
{
public function findAll(): BooksCollection;
public function findBy(SpecificationInterface $spec): BooksCollection;
}
Available Operations
Collections provide operations grouped by capability:
| Capability | Methods |
|---|---|
| Readable | first(), last(), isEmpty(), items(), values() |
| Functional | map(), filter(), reduce(), each() |
| Transformable | slice(), take(), sort(), reverse(), unique() |
| Searchable | find(), findKey(), findAll(), indexOf(), lastIndexOf() |
| Mutable | add(), set(), remove(), clear() |
| Navigable | key(), current(), next(), previous(), rewind() |
Untyped Collections
For generic collections without type enforcement, extend AbstractCollection directly:
Best Practices
- One collection per entity type
- Return collections from repositories, not raw arrays
- Prefer
map/filterover imperative loops - Let the collection enforce element types