4.3. Entity-Attribute-Value (EAV) __

Het Entity-attribute-value (EAV) patroon om het EAV-model met PHP te implementeren.

4.3.1. Doel

Het Entity-attribute-value (EAV) -model is een gegevensmodel om entiteiten te beschrijven waarvan het aantal attributen (eigenschappen, parameters) dat kan worden gebruikt om ze te beschrijven potentieel enorm is, maar het aantal dat daadwerkelijk van toepassing is op een bepaalde entiteit is relatief bescheiden.

4.3.2. UML Diagram

EAV UML Diagram

4.3.3. Code

Je kan deze broncode terugvinden op GitHub

Entity.php

 1<?php
 2
 3declare(strict_types=1);
 4
 5namespace DesignPatterns\More\EAV;
 6
 7use SplObjectStorage;
 8
 9class Entity implements \Stringable
10{
11    /**
12     * @var SplObjectStorage<Value,Value>
13     */
14    private $values;
15
16    /**
17     * @param Value[] $values
18     */
19    public function __construct(private string $name, array $values)
20    {
21        $this->values = new SplObjectStorage();
22
23        foreach ($values as $value) {
24            $this->values->attach($value);
25        }
26    }
27
28    public function __toString(): string
29    {
30        $text = [$this->name];
31
32        foreach ($this->values as $value) {
33            $text[] = (string) $value;
34        }
35
36        return join(', ', $text);
37    }
38}

Attribute.php

 1<?php
 2
 3declare(strict_types=1);
 4
 5namespace DesignPatterns\More\EAV;
 6
 7use SplObjectStorage;
 8
 9class Attribute implements \Stringable
10{
11    private SplObjectStorage $values;
12
13    public function __construct(private string $name)
14    {
15        $this->values = new SplObjectStorage();
16    }
17
18    public function addValue(Value $value): void
19    {
20        $this->values->attach($value);
21    }
22
23    public function getValues(): SplObjectStorage
24    {
25        return $this->values;
26    }
27
28    public function __toString(): string
29    {
30        return $this->name;
31    }
32}

Value.php

 1<?php
 2
 3declare(strict_types=1);
 4
 5namespace DesignPatterns\More\EAV;
 6
 7class Value implements \Stringable
 8{
 9    public function __construct(private Attribute $attribute, private string $name)
10    {
11        $attribute->addValue($this);
12    }
13
14    public function __toString(): string
15    {
16        return sprintf('%s: %s', (string) $this->attribute, $this->name);
17    }
18}

4.3.4. Test

Tests/EAVTest.php

 1<?php
 2
 3declare(strict_types=1);
 4
 5namespace DesignPatterns\More\EAV\Tests;
 6
 7use DesignPatterns\More\EAV\Attribute;
 8use DesignPatterns\More\EAV\Entity;
 9use DesignPatterns\More\EAV\Value;
10use PHPUnit\Framework\TestCase;
11
12class EAVTest extends TestCase
13{
14    public function testCanAddAttributeToEntity(): void
15    {
16        $colorAttribute = new Attribute('color');
17        $colorSilver = new Value($colorAttribute, 'silver');
18        $colorBlack = new Value($colorAttribute, 'black');
19
20        $memoryAttribute = new Attribute('memory');
21        $memory8Gb = new Value($memoryAttribute, '8GB');
22
23        $entity = new Entity('MacBook Pro', [$colorSilver, $colorBlack, $memory8Gb]);
24
25        $this->assertEquals('MacBook Pro, color: silver, color: black, memory: 8GB', (string) $entity);
26    }
27}