4.3. Entity-Attribute-Value (EAV)

The Entity–attribute–value (EAV) pattern in order to implement EAV model with PHP.

4.3.1. Amaç

Varlık-Özellik-Değer modeli, onları tanımlamak için kullanılabilecek özelliklerin (properties, parameters) sayısının büyük olabileceği varlıkları tanımlamak için bir veri modeli olmakla birlikte, aslında belirli ve nispeten ılımlı bir varlık için geçerli olacak sayıdır.

4.3.2. UML Diyagramı

EAV UML Diyagramı

4.3.3. Kod

Bu kodu Github üzerinde de bulabilirsiniz.

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}