1.5. Prototype

1.5.1. Zweck

Um die Kosten der Erzeugung von Objekten über den normalen Weg (new Foo()) zu vermeiden und stattdessen einen Prototyp zu erzeugen, der bei Bedarf gecloned werden kann.

1.5.2. Beispiele

  • Große Mengen von Daten (z.B. 1 Mio. Zeilen werden in einer Datenbank über ein ORM erzeugt).

1.5.3. UML Diagramm

Alt Prototype UML Diagram

1.5.4. Code

Du findest den Code auch auf GitHub

BookPrototype.php

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php

declare(strict_types=1);

namespace DesignPatterns\Creational\Prototype;

abstract class BookPrototype
{
    protected string $title;
    protected string $category;

    abstract public function __clone();

    public function getTitle(): string
    {
        return $this->title;
    }

    public function setTitle(string $title): void
    {
        $this->title = $title;
    }
}

BarBookPrototype.php

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<?php

declare(strict_types=1);

namespace DesignPatterns\Creational\Prototype;

class BarBookPrototype extends BookPrototype
{
    protected string $category = 'Bar';

    public function __clone()
    {
    }
}

FooBookPrototype.php

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<?php

declare(strict_types=1);

namespace DesignPatterns\Creational\Prototype;

class FooBookPrototype extends BookPrototype
{
    protected string $category = 'Foo';

    public function __clone()
    {
    }
}

1.5.5. Теst

Tests/PrototypeTest.php

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?php

declare(strict_types=1);

namespace DesignPatterns\Creational\Prototype\Tests;

use DesignPatterns\Creational\Prototype\BarBookPrototype;
use DesignPatterns\Creational\Prototype\FooBookPrototype;
use PHPUnit\Framework\TestCase;

class PrototypeTest extends TestCase
{
    public function testCanGetFooBook()
    {
        $fooPrototype = new FooBookPrototype();
        $barPrototype = new BarBookPrototype();

        for ($i = 0; $i < 10; $i++) {
            $book = clone $fooPrototype;
            $book->setTitle('Foo Book No ' . $i);
            $this->assertInstanceOf(FooBookPrototype::class, $book);
        }

        for ($i = 0; $i < 5; $i++) {
            $book = clone $barPrototype;
            $book->setTitle('Bar Book No ' . $i);
            $this->assertInstanceOf(BarBookPrototype::class, $book);
        }
    }
}