1.5. Прототип (Prototype)

1.5.1. Назначение

Помогает избежать затрат на создание объектов стандартным способом (new Foo()), а вместо этого создаёт прототип и затем клонирует его.

1.5.2. Примеры

  • Большие объемы данных (например, создать 1000000 строк в базе данных сразу через ORM).

1.5.3. Диаграмма UML

Alt Prototype UML Diagram

1.5.4. Код

Вы можете найти этот код на GitHub

BookPrototype.php

 1<?php
 2
 3declare(strict_types=1);
 4
 5namespace DesignPatterns\Creational\Prototype;
 6
 7abstract class BookPrototype
 8{
 9    protected string $title;
10    protected string $category;
11
12    abstract public function __clone();
13
14    final public function getTitle(): string
15    {
16        return $this->title;
17    }
18
19    final public function setTitle(string $title): void
20    {
21        $this->title = $title;
22    }
23}

BarBookPrototype.php

 1<?php
 2
 3declare(strict_types=1);
 4
 5namespace DesignPatterns\Creational\Prototype;
 6
 7class BarBookPrototype extends BookPrototype
 8{
 9    protected string $category = 'Bar';
10
11    public function __clone()
12    {
13    }
14}

FooBookPrototype.php

 1<?php
 2
 3declare(strict_types=1);
 4
 5namespace DesignPatterns\Creational\Prototype;
 6
 7class FooBookPrototype extends BookPrototype
 8{
 9    protected string $category = 'Foo';
10
11    public function __clone()
12    {
13    }
14}

1.5.5. Тест

Tests/PrototypeTest.php

 1<?php
 2
 3declare(strict_types=1);
 4
 5namespace DesignPatterns\Creational\Prototype\Tests;
 6
 7use DesignPatterns\Creational\Prototype\BarBookPrototype;
 8use DesignPatterns\Creational\Prototype\FooBookPrototype;
 9use PHPUnit\Framework\TestCase;
10
11class PrototypeTest extends TestCase
12{
13    public function testCanGetFooBook()
14    {
15        $fooPrototype = new FooBookPrototype();
16        $barPrototype = new BarBookPrototype();
17
18        for ($i = 0; $i < 10; $i++) {
19            $book = clone $fooPrototype;
20            $book->setTitle('Foo Book No ' . $i);
21            $this->assertInstanceOf(FooBookPrototype::class, $book);
22        }
23
24        for ($i = 0; $i < 5; $i++) {
25            $book = clone $barPrototype;
26            $book->setTitle('Bar Book No ' . $i);
27            $this->assertInstanceOf(BarBookPrototype::class, $book);
28        }
29    }
30}