4.3. Entity-Attribute-Value (EAV)

Le pattern Entité-attribut-valeur (EAV) afin d’implémenter le modèle EAV avec PHP.

4.3.1. Rôle

Le modèle Entité-attribut-valeur (EAV) est un modèle de données permettant de décrire des entités pour lesquelles le nombre d’attributs (propriétés, paramètres) pouvant être utilisés pour les décrire est potentiellement vaste, mais le nombre qui s’appliquera réellement à une entité donnée est relativement modeste.

4.3.2. Diagramme UML

EAV UML Diagram

4.3.3. Code

Vous pouvez également trouver ce code sur 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}