Главная страница

Патерны программирования. DesignPatternsphp documentation


Скачать 1.98 Mb.
НазваниеDesignPatternsphp documentation
АнкорПатерны программирования
Дата06.02.2023
Размер1.98 Mb.
Формат файлаpdf
Имя файлаdesignpatternsphp-readthedocs-io-ru-latest.pdf
ТипДокументы
#923605
страница1 из 9
  1   2   3   4   5   6   7   8   9

DesignPatternsPHP Documentation
Выпуск 1.0
Dominik Liebler and contributors нояб. 14, 2022

Оглавление
1
Паттерны
3 1.1
Порождающие шаблоны проектирования (Creational)
3 1.1.1
Абстрактная фабрика (Abstract Factory)
3 1.1.2
Строитель (Builder)
9 1.1.3
Фабричный Метод (Factory Method)
. . . . . . . . . . . . . . . . . . . . . . . . . . 15 1.1.4
Объектный пул (Pool)
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 1.1.5
Прототип (Prototype)
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 1.1.6
Простая Фабрика (Simple Factory)
. . . . . . . . . . . . . . . . . . . . . . . . . . . 25 1.1.7
Одиночка (Singleton)
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 1.1.8
Статическая Фабрика (Static Factory)
. . . . . . . . . . . . . . . . . . . . . . . . . 30 1.2
Структурные шаблоны проектирования (Structural)
. . . . . . . . . . . . . . . . . . . . . 33 1.2.1
Адаптер (Adapter / Wrapper)
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 1.2.2
Мост (Bridge)
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 1.2.3
Компоновщик (Composite)
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 1.2.4
Преобразователь Данных (Data Mapper)
. . . . . . . . . . . . . . . . . . . . . . . . 46 1.2.5
Декоратор (Decorator)
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 1.2.6
Внедрение Зависимости (Dependency Injection)
. . . . . . . . . . . . . . . . . . . . 54 1.2.7
Фасад (Facade)
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 1.2.8
Текучий Интерфейс (Fluent Interface)
. . . . . . . . . . . . . . . . . . . . . . . . . 61 1.2.9
Приспособленец (Flyweight)
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64 1.2.10 Прокси (Proxy)
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69 1.2.11 Реестр (Registry)
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73 1.3
Поведенческие шаблоны проектирования (Behavioral)
. . . . . . . . . . . . . . . . . . . . 76 1.3.1
Цепочка Обязанностей (Chain Of Responsibilities)
. . . . . . . . . . . . . . . . . . 76 1.3.2
Команда (Command)
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80 1.3.3
Интепретатор (Interpreter)
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87 1.3.4
Итератор (Iterator)
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92 1.3.5
Посредник (Mediator)
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97 1.3.6
Хранитель (Memento)
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101 1.3.7
Объект Null (Null Object)
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106 1.3.8
Наблюдатель (Observer)
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110 1.3.9
Спецификация (Specification)
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113 1.3.10 Состояние (State)
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118 1.3.11 Стратегия (Strategy)
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122 1.3.12 Шаблонный Метод (Template Method)
. . . . . . . . . . . . . . . . . . . . . . . . . 127 1.3.13 Посетитель (Visitor)
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
i

1.4
Дополнительно
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137 1.4.1
Локатор Служб (Service Locator)
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 137 1.4.2
Хранилище (Repository)
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141 1.4.3
Сущность-Атрибут-Значение
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150
ii

DesignPatternsPHP Documentation, Выпуск 1.0
This is a collection of known design patterns and some sample code how to implement them in PHP. Every pattern has a small list of examples.
Я считаю, проблема паттернов в том, что люди часто знакомы с ними, но не представляют как их применять.
Оглавление
1

DesignPatternsPHP Documentation, Выпуск 1.0 2
Оглавление

Глава
1
Паттерны
Паттерны могут быть условно сгруппированы в три различные категории. Нажмите на заголовок каждой страницы с паттерном для детального объяснения паттерна в Википедии.
1.1 Порождающие шаблоны проектирования (Creational)
В разработке программного обеспечения, Порождающие шаблоны проектирования – это паттерны,
которые имеют дело с механизмами создания объекта и пытаются создать объекты в порядке, подхо- дящем к ситуации. Обычная форма создания объекта может привести к проблемам проектирования или увеличивать сложность конструкции. Порождающие шаблоны проектирования решают эту про- блему, определённым образом контролируя процесс создания объекта.
1.1.1 Абстрактная фабрика (Abstract Factory)
Назначение
To create series of related or dependent objects without specifying their concrete classes. Usually the created classes all implement the same interface. The client of the abstract factory does not care about how these objects are created, it just knows how they go together.
3

DesignPatternsPHP Documentation, Выпуск 1.0 4
Глава 1. Паттерны

DesignPatternsPHP Documentation, Выпуск 1.0
Диаграмма UML
1.1. Порождающие шаблоны проектирования (Creational)
5

DesignPatternsPHP Documentation, Выпуск 1.0
Код
Вы можете найти этот код на
GitHub
WriterFactory.php
1
2 3
namespace
DesignPatterns\Creational\AbstractFactory;
4 5
interface
WriterFactory
6
{
7
public function createCsvWriter
()
:
CsvWriter;
8
public function createJsonWriter
()
:
JsonWriter;
9
}
CsvWriter.php
1
2 3
namespace
DesignPatterns\Creational\AbstractFactory;
4 5
interface
CsvWriter
6
{
7
public function write
(
array
$line
)
:
string;
8
}
JsonWriter.php
1
2 3
namespace
DesignPatterns\Creational\AbstractFactory;
4 5
interface
JsonWriter
6
{
7
public function write
(
array
$data
, bool
$formatted
)
:
string;
8
}
UnixCsvWriter.php
1
2 3
namespace
DesignPatterns\Creational\AbstractFactory;
4 5
class
UnixCsvWriter implements
CsvWriter
6
{
7
public function write
(
array
$line
)
:
string
8
{
9
return join
(
','
,
$line
)
"\n"
;
10
}
11
}
UnixJsonWriter.php
6
Глава 1. Паттерны

DesignPatternsPHP Documentation, Выпуск 1.0 1
2 3
namespace
DesignPatterns\Creational\AbstractFactory;
4 5
class
UnixJsonWriter implements
JsonWriter
6
{
7
public function write
(
array
$data
, bool
$formatted
)
:
string
8
{
9
$options
=
0
;
10 11
if
(
$formatted
) {
12
$options
=
JSON_PRETTY_PRINT;
13
}
14 15
return json_encode
(
$data
,
$options
);
16
}
17
}
UnixWriterFactory.php
1
2 3
namespace
DesignPatterns\Creational\AbstractFactory;
4 5
class
UnixWriterFactory implements
WriterFactory
6
{
7
public function createCsvWriter
()
:
CsvWriter
8
{
9
return new
UnixCsvWriter();
10
}
11 12
public function createJsonWriter
()
:
JsonWriter
13
{
14
return new
UnixJsonWriter();
15
}
16
}
WinCsvWriter.php
1
2 3
namespace
DesignPatterns\Creational\AbstractFactory;
4 5
class
WinCsvWriter implements
CsvWriter
6
{
7
public function write
(
array
$line
)
:
string
8
{
9
return join
(
','
,
$line
)
"\r\n"
;
10
}
11
}
WinJsonWriter.php
1.1. Порождающие шаблоны проектирования (Creational)
7

DesignPatternsPHP Documentation, Выпуск 1.0 1
2 3
namespace
DesignPatterns\Creational\AbstractFactory;
4 5
class
WinJsonWriter implements
JsonWriter
6
{
7
public function write
(
array
$data
, bool
$formatted
)
:
string
8
{
9
$options
=
0
;
10 11
if
(
$formatted
) {
12
$options
=
JSON_PRETTY_PRINT;
13
}
14 15
return json_encode
(
$data
,
$options
);
16
}
17
}
WinWriterFactory.php
1
2 3
namespace
DesignPatterns\Creational\AbstractFactory;
4 5
class
WinWriterFactory implements
WriterFactory
6
{
7
public function createCsvWriter
()
:
CsvWriter
8
{
9
return new
WinCsvWriter();
10
}
11 12
public function createJsonWriter
()
:
JsonWriter
13
{
14
return new
WinJsonWriter();
15
}
16
}
Тест
Tests/AbstractFactoryTest.php
1
2 3
declare
(strict_types
=
1
);
4 5
namespace
DesignPatterns\Creational\AbstractFactory\Tests;
6 7
use
DesignPatterns\Creational\AbstractFactory\CsvWriter;
8
use
DesignPatterns\Creational\AbstractFactory\JsonWriter;
9
use
DesignPatterns\Creational\AbstractFactory\UnixWriterFactory;
10
use
DesignPatterns\Creational\AbstractFactory\WinWriterFactory;
11
use
DesignPatterns\Creational\AbstractFactory\WriterFactory;
(continues on next page)
8
Глава 1. Паттерны

DesignPatternsPHP Documentation, Выпуск 1.0
(продолжение с предыдущей страницы)
12
use
PHPUnit\Framework\TestCase;
13 14
class
AbstractFactoryTest extends
TestCase
15
{
16
public function provideFactory
()
17
{
18
return
[
19
[
new
UnixWriterFactory()],
20
[
new
WinWriterFactory()]
21
];
22
}
23 24
/**
25
* @dataProvider provideFactory
26
*/
27
public function testCanCreateCsvWriterOnUnix
(WriterFactory
$writerFactory
)
28
{
29
$this
->
assertInstanceOf
(JsonWriter
::
class
,
$writerFactory
->
createJsonWriter
());
30
$this
->
assertInstanceOf
(CsvWriter
::
class
,
$writerFactory
->
createCsvWriter
());
31
}
32
}
1.1.2 Строитель (Builder)
Назначение
Строитель — это интерфейс для производства частей сложного объекта.
Иногда, если Строитель лучше знает о том, что он строит, этот интерфейс может быть абстрактным классом с методами по-умолчанию (адаптер).
Если у вас есть сложное дерево наследования для объектов, логично иметь сложное дерево наследо- вания и для их строителей.
Примечание: Строители могут иметь текучий интерфейс
, например, строитель макетов в PHPUnit.
Примеры
• PHPUnit: Mock Builder
1.1. Порождающие шаблоны проектирования (Creational)
9

DesignPatternsPHP Documentation, Выпуск 1.0
Диаграмма UML
Код
Вы можете найти этот код на
GitHub
Director.php
1
2 3
declare
(strict_types
=
1
);
4 5
namespace
DesignPatterns\Creational\Builder;
6 7
use
DesignPatterns\Creational\Builder\Parts\Vehicle;
8 9
/**
10
* Director is part of the builder pattern. It knows the interface of the builder
11
* and builds a complex object with the help of the builder
12
*
13
* You can also inject many builders instead of one to build more complex objects
14
*/
(continues on next page)
10
Глава 1. Паттерны

DesignPatternsPHP Documentation, Выпуск 1.0
(продолжение с предыдущей страницы)
15
class
Director
16
{
17
public function build
(Builder
$builder
)
:
Vehicle
18
{
19
$builder
->
createVehicle
();
20
$builder
->
addDoors
();
21
$builder
->
addEngine
();
22
$builder
->
addWheel
();
23 24
return
$builder
->
getVehicle
();
25
}
26
}
Builder.php
1
2 3
declare
(strict_types
=
1
);
4 5
namespace
DesignPatterns\Creational\Builder;
6 7
use
DesignPatterns\Creational\Builder\Parts\Vehicle;
8 9
interface
Builder
10
{
11
public function createVehicle
()
:
void;
12 13
public function addWheel
()
:
void;
14 15
public function addEngine
()
:
void;
16 17
public function addDoors
()
:
void;
18 19
public function getVehicle
()
:
Vehicle;
20
}
TruckBuilder.php
1
2 3
declare
(strict_types
=
1
);
4 5
namespace
DesignPatterns\Creational\Builder;
6 7
use
DesignPatterns\Creational\Builder\Parts\Door;
8
use
DesignPatterns\Creational\Builder\Parts\Engine;
9
use
DesignPatterns\Creational\Builder\Parts\Wheel;
10
use
DesignPatterns\Creational\Builder\Parts\Truck;
11
use
DesignPatterns\Creational\Builder\Parts\Vehicle;
12 13
class
TruckBuilder implements
Builder
14
{
(continues on next page)
1.1. Порождающие шаблоны проектирования (Creational)
11

DesignPatternsPHP Documentation, Выпуск 1.0
(продолжение с предыдущей страницы)
15
private
Truck
$truck
;
16 17
public function addDoors
()
:
void
18
{
19
$this
->
truck
->
setPart
(
'rightDoor'
,
new
Door());
20
$this
->
truck
->
setPart
(
'leftDoor'
,
new
Door());
21
}
22 23
public function addEngine
()
:
void
24
{
25
$this
->
truck
->
setPart
(
'truckEngine'
,
new
Engine());
26
}
27 28
public function addWheel
()
:
void
29
{
30
$this
->
truck
->
setPart
(
'wheel1'
,
new
Wheel());
31
$this
->
truck
->
setPart
(
'wheel2'
,
new
Wheel());
32
$this
->
truck
->
setPart
(
'wheel3'
,
new
Wheel());
33
$this
->
truck
->
setPart
(
'wheel4'
,
new
Wheel());
34
$this
->
truck
->
setPart
(
'wheel5'
,
new
Wheel());
35
$this
->
truck
->
setPart
(
'wheel6'
,
new
Wheel());
36
}
37 38
public function createVehicle
()
:
void
39
{
40
$this
->
truck
=
new
Truck();
41
}
42 43
public function getVehicle
()
:
Vehicle
44
{
45
return
$this
->
truck
;
46
}
47
}
CarBuilder.php
1
2 3
declare
(strict_types
=
1
);
4 5
namespace
DesignPatterns\Creational\Builder;
6 7
use
DesignPatterns\Creational\Builder\Parts\Door;
8
use
DesignPatterns\Creational\Builder\Parts\Engine;
9
use
DesignPatterns\Creational\Builder\Parts\Wheel;
10
use
DesignPatterns\Creational\Builder\Parts\Car;
11
use
DesignPatterns\Creational\Builder\Parts\Vehicle;
12 13
class
CarBuilder implements
Builder
14
{
15
private
Car
$car
;
16
(continues on next page)
12
Глава 1. Паттерны

DesignPatternsPHP Documentation, Выпуск 1.0
(продолжение с предыдущей страницы)
17
public function addDoors
()
:
void
18
{
19
$this
->
car
->
setPart
(
'rightDoor'
,
new
Door());
20
$this
->
car
->
setPart
(
'leftDoor'
,
new
Door());
21
$this
->
car
->
setPart
(
'trunkLid'
,
new
Door());
22
}
23 24
public function addEngine
()
:
void
25
{
26
$this
->
car
->
setPart
(
'engine'
,
new
Engine());
27
}
28 29
public function addWheel
()
:
void
30
{
31
$this
->
car
->
setPart
(
'wheelLF'
,
new
Wheel());
32
$this
->
car
->
setPart
(
'wheelRF'
,
new
Wheel());
33
$this
->
car
->
setPart
(
'wheelLR'
,
new
Wheel());
34
$this
->
car
->
setPart
(
'wheelRR'
,
new
Wheel());
35
}
36 37
public function createVehicle
()
:
void
38
{
39
$this
->
car
=
new
Car();
40
}
41 42
public function getVehicle
()
:
Vehicle
43
{
44
return
$this
->
car
;
45
}
46
}
Parts/Vehicle.php
1
2 3
declare
(strict_types
=
1
);
4 5
namespace
DesignPatterns\Creational\Builder\Parts;
6 7
abstract class
Vehicle
8
{
9
final public function setPart
(string
$key
, object
$value
)
10
{
11
}
12
}
Parts/Truck.php
1
2 3
declare
(strict_types
=
1
);
4
(continues on next page)
1.1. Порождающие шаблоны проектирования (Creational)
13

DesignPatternsPHP Documentation, Выпуск 1.0
(продолжение с предыдущей страницы)
5
namespace
DesignPatterns\Creational\Builder\Parts;
6 7
class
Truck extends
Vehicle
8
{
9
}
Parts/Car.php
1
2 3
declare
(strict_types
=
1
);
4 5
namespace
DesignPatterns\Creational\Builder\Parts;
6 7
class
Car extends
Vehicle
8
{
9
}
Parts/Engine.php
1
2 3
declare
(strict_types
=
1
);
4 5
namespace
DesignPatterns\Creational\Builder\Parts;
6 7
class
Engine
8
{
9
}
Parts/Wheel.php
1
2 3
declare
(strict_types
=
1
);
4 5
namespace
DesignPatterns\Creational\Builder\Parts;
6 7
class
Wheel
8
{
9
}
Parts/Door.php
1
2 3
declare
(strict_types
=
1
);
4 5
namespace
DesignPatterns\Creational\Builder\Parts;
6 7
class
Door
8
{
9
}
14
Глава 1. Паттерны

DesignPatternsPHP Documentation, Выпуск 1.0
Тест
Tests/DirectorTest.php
1
2 3
declare
(strict_types
=
1
);
4 5
namespace
DesignPatterns\Creational\Builder\Tests;
6 7
use
DesignPatterns\Creational\Builder\Parts\Car;
8
use
DesignPatterns\Creational\Builder\Parts\Truck;
9
use
DesignPatterns\Creational\Builder\TruckBuilder;
10
use
DesignPatterns\Creational\Builder\CarBuilder;
11
use
DesignPatterns\Creational\Builder\Director;
12
use
PHPUnit\Framework\TestCase;
13 14
class
DirectorTest extends
TestCase
15
{
16
public function testCanBuildTruck
()
17
{
18
$truckBuilder
=
new
TruckBuilder();
19
$newVehicle
=
(
new
Director())
->
build
(
$truckBuilder
);
20 21
$this
->
assertInstanceOf
(Truck
::
class
,
$newVehicle
);
22
}
23 24
public function testCanBuildCar
()
25
{
26
$carBuilder
=
new
CarBuilder();
27
$newVehicle
=
(
new
Director())
->
build
(
$carBuilder
);
28 29
$this
->
assertInstanceOf
(Car
::
class
,
$newVehicle
);
30
}
31
}
1.1.3 Фабричный Метод (Factory Method)
Назначение
Выгодное отличие от SimpleFactory в том, что вы можете вынести реализацию создания объектов в подклассы.
В простых случаях, этот абстрактный класс может быть только интерфейсом.
Этот паттерн является «настоящим» Шаблоном Проектирования, потому что он следует «Принципу инверсии зависимостей» также известному как «D» в
S.O.L.I.D
Это означает, что класс FactoryMethod зависит от абстракций, а не от конкретных классов. Это суще- ственный плюс в сравнении с SimpleFactory или StaticFactory.
1.1. Порождающие шаблоны проектирования (Creational)
15

DesignPatternsPHP Documentation, Выпуск 1.0
Диаграмма UML
16
Глава 1. Паттерны

DesignPatternsPHP Documentation, Выпуск 1.0
Код
Вы можете найти этот код на
GitHub
Logger.php
1
2 3
declare
(strict_types
=
1
);
4 5
namespace
DesignPatterns\Creational\FactoryMethod;
6 7
interface
Logger
8
{
9
public function log
(string
$message
);
10
}
StdoutLogger.php
1
2 3
declare
(strict_types
=
1
);
4 5
namespace
DesignPatterns\Creational\FactoryMethod;
6 7
class
StdoutLogger implements
Logger
8
{
9
public function log
(string
$message
)
10
{
11
echo
$message
;
12
}
13
}
FileLogger.php
1
2 3
declare
(strict_types
=
1
);
4 5
namespace
DesignPatterns\Creational\FactoryMethod;
6 7
class
FileLogger implements
Logger
8
{
9
public function
__construct
(
private string
$filePath
)
10
{
11
}
12 13
public function log
(string
$message
)
14
{
15
file_put_contents
(
$this
->
filePath
,
$message
PHP_EOL, FILE_APPEND);
16
}
17
}
LoggerFactory.php
1.1. Порождающие шаблоны проектирования (Creational)
17

DesignPatternsPHP Documentation, Выпуск 1.0 1
2 3
declare
(strict_types
=
1
);
4 5
namespace
DesignPatterns\Creational\FactoryMethod;
6 7
interface
LoggerFactory
8
{
9
public function createLogger
()
:
Logger;
10
}
StdoutLoggerFactory.php
1
2 3
declare
(strict_types
=
1
);
4 5
namespace
DesignPatterns\Creational\FactoryMethod;
6 7
class
StdoutLoggerFactory implements
LoggerFactory
8
{
9
public function createLogger
()
:
Logger
10
{
11
return new
StdoutLogger();
12
}
13
}
FileLoggerFactory.php
1
2 3
declare
(strict_types
=
1
);
4 5
namespace
DesignPatterns\Creational\FactoryMethod;
6 7
class
FileLoggerFactory implements
LoggerFactory
8
{
9
public function
__construct
(
private string
$filePath
)
10
{
11
}
12 13
public function createLogger
()
:
Logger
14
{
15
return new
FileLogger(
$this
->
filePath
);
16
}
17
}
18
Глава 1. Паттерны

DesignPatternsPHP Documentation, Выпуск 1.0
Тест
Tests/FactoryMethodTest.php
1
2 3
declare
(strict_types
=
1
);
4 5
namespace
DesignPatterns\Creational\FactoryMethod\Tests;
6 7
use
DesignPatterns\Creational\FactoryMethod\FileLogger;
8
use
DesignPatterns\Creational\FactoryMethod\FileLoggerFactory;
9
use
DesignPatterns\Creational\FactoryMethod\StdoutLogger;
10
use
DesignPatterns\Creational\FactoryMethod\StdoutLoggerFactory;
11
use
PHPUnit\Framework\TestCase;
12 13
class
FactoryMethodTest extends
TestCase
14
{
15
public function testCanCreateStdoutLogging
()
16
{
17
$loggerFactory
=
new
StdoutLoggerFactory();
18
$logger
=
$loggerFactory
->
createLogger
();
19 20
$this
->
assertInstanceOf
(StdoutLogger
::
class
,
$logger
);
21
}
22 23
public function testCanCreateFileLogging
()
24
{
25
$loggerFactory
=
new
FileLoggerFactory(
sys_get_temp_dir
());
26
$logger
=
$loggerFactory
->
createLogger
();
27 28
$this
->
assertInstanceOf
(FileLogger
::
class
,
$logger
);
29
}
30
}
1.1.4 Объектный пул (Pool)
Назначение
Порождающий паттерн, который предоставляет набор заранее инициализированных объектов, готовых к использованию («пул»), что не требует каждый раз создавать и уничтожать их.
Хранение объектов в пуле может заметно повысить производительность в ситуациях, когда стоимость и скорость инициализации экземпляра класса высоки, а количество одновременно используемых эк- земпляров в любой момент времени является низким. Время на получение объекта из пула легко прогнозируется, тогда как создание нового объекта (особенно с сетевым оверхедом) может занимать неопределенное время.
Однако эти преимущества в основном относятся к объектам, которые изначально являются дорого- стоящими по времени создания. Например, соединения с базой данных, соединения сокетов, потоков или инициализация больших графических объектов, таких как шрифты или растровые изображения. В
некоторых ситуациях, использование простого пула объектов (которые не зависят от внешних ресурсов,
а только занимают память) может оказаться неэффективным и приведёт к снижению производитель- ности.
1.1. Порождающие шаблоны проектирования (Creational)
19

DesignPatternsPHP Documentation, Выпуск 1.0
Диаграмма UML
20
Глава 1. Паттерны

DesignPatternsPHP Documentation, Выпуск 1.0
Код
Вы можете найти этот код на
GitHub
WorkerPool.php
1
2 3
declare
(strict_types
=
1
);
4 5
namespace
DesignPatterns\Creational\Pool;
6 7
use
Countable;
8 9
class
WorkerPool implements
Countable
10
{
11
/**
12
* @var StringReverseWorker[]
13
*/
14
private array
$occupiedWorkers
=
[];
15 16
/**
17
* @var StringReverseWorker[]
18
*/
19
private array
$freeWorkers
=
[];
20 21
public function get
()
:
StringReverseWorker
22
{
23
if
(
count
(
$this
->
freeWorkers
)
===
0
) {
24
$worker
=
new
StringReverseWorker();
25
}
else
{
26
$worker
=
array_pop
(
$this
->
freeWorkers
);
27
}
28 29
$this
->
occupiedWorkers
[
spl_object_hash
(
$worker
)]
=
$worker
;
30 31
return
$worker
;
32
}
33 34
public function dispose
(StringReverseWorker
$worker
)
:
void
35
{
36
$key
=
spl_object_hash
(
$worker
);
37
if
(
isset
(
$this
->
occupiedWorkers
[
$key
])) {
38
unset
(
$this
->
occupiedWorkers
[
$key
]);
39
$this
->
freeWorkers
[
$key
]
=
$worker
;
40
}
41
}
42 43
public function count
()
:
int
44
{
45
return count
(
$this
->
occupiedWorkers
)
+
count
(
$this
->
freeWorkers
);
46
}
47
}
StringReverseWorker.php
1.1. Порождающие шаблоны проектирования (Creational)
21

DesignPatternsPHP Documentation, Выпуск 1.0 1
2 3
declare
(strict_types
=
1
);
4 5
namespace
DesignPatterns\Creational\Pool;
6 7
class
StringReverseWorker
8
{
9
public function run
(string
$text
)
:
string
10
{
11
return strrev
(
$text
);
12
}
13
}
Тест
Tests/PoolTest.php
1
2 3
declare
(strict_types
=
1
);
4 5
namespace
DesignPatterns\Creational\Pool\Tests;
6 7
use
DesignPatterns\Creational\Pool\WorkerPool;
8
use
PHPUnit\Framework\TestCase;
9 10
class
PoolTest extends
TestCase
11
{
12
public function testCanGetNewInstancesWithGet
()
13
{
14
$pool
=
new
WorkerPool();
15
$worker1
=
$pool
->
get
();
16
$worker2
=
$pool
->
get
();
17 18
$this
->
assertCount
(
2
,
$pool
);
19
$this
->
assertNotSame
(
$worker1
,
$worker2
);
20
}
21 22
public function testCanGetSameInstanceTwiceWhenDisposingItFirst
()
23
{
24
$pool
=
new
WorkerPool();
25
$worker1
=
$pool
->
get
();
26
$pool
->
dispose
(
$worker1
);
27
$worker2
=
$pool
->
get
();
28 29
$this
->
assertCount
(
1
,
$pool
);
30
$this
->
assertSame
(
$worker1
,
$worker2
);
31
}
32
}
22
Глава 1. Паттерны

DesignPatternsPHP Documentation, Выпуск 1.0 1.1.5 Прототип (Prototype)
Назначение
Помогает избежать затрат на создание объектов стандартным способом (new Foo()), а вместо этого создаёт прототип и затем клонирует его.
Примеры
• Большие объемы данных (например, создать 1000000 строк в базе данных сразу через ORM).
Диаграмма UML
Код
Вы можете найти этот код на
GitHub
BookPrototype.php
1
2 3
declare
(strict_types
=
1
);
4 5
namespace
DesignPatterns\Creational\Prototype;
6 7
abstract class
BookPrototype
8
{
9
protected string
$title
;
10
protected string
$category
;
11 12
abstract public function
__clone
();
13
(continues on next page)
1.1. Порождающие шаблоны проектирования (Creational)
23

DesignPatternsPHP Documentation, Выпуск 1.0
(продолжение с предыдущей страницы)
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
2 3
declare
(strict_types
=
1
);
4 5
namespace
DesignPatterns\Creational\Prototype;
6 7
class
BarBookPrototype extends
BookPrototype
8
{
9
protected string
$category
=
'Bar'
;
10 11
public function
__clone
()
12
{
13
}
14
}
FooBookPrototype.php
1
2 3
declare
(strict_types
=
1
);
4 5
namespace
DesignPatterns\Creational\Prototype;
6 7
class
FooBookPrototype extends
BookPrototype
8
{
9
protected string
$category
=
'Foo'
;
10 11
public function
__clone
()
12
{
13
}
14
}
24
Глава 1. Паттерны

DesignPatternsPHP Documentation, Выпуск 1.0
Тест
Tests/PrototypeTest.php
1
2 3
declare
(strict_types
=
1
);
4 5
namespace
DesignPatterns\Creational\Prototype\Tests;
6 7
use
DesignPatterns\Creational\Prototype\BarBookPrototype;
8
use
DesignPatterns\Creational\Prototype\FooBookPrototype;
9
use
PHPUnit\Framework\TestCase;
10 11
class
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
}
1.1.6 Простая Фабрика (Simple Factory)
Назначение
SimpleFactory в примере ниже, это паттерн «Простая Фабрика».
Она отличается от Статической Фабрики тем, что собственно не является статической. Таким обра- зом, вы можете иметь множество фабрик с разными параметрами. Простая фабрика всегда должна быть предпочтительнее Статической фабрики!
1.1. Порождающие шаблоны проектирования (Creational)
25

DesignPatternsPHP Documentation, Выпуск 1.0
Диаграмма UML
Код
Вы можете найти этот код на
GitHub
SimpleFactory.php
1
2 3
declare
(strict_types
=
1
);
4 5
namespace
DesignPatterns\Creational\SimpleFactory;
6 7
class
SimpleFactory
8
{
9
public function createBicycle
()
:
Bicycle
10
{
11
return new
Bicycle();
12
}
13
}
Bicycle.php
1
2 3
declare
(strict_types
=
1
);
4
(continues on next page)
26
Глава 1. Паттерны

DesignPatternsPHP Documentation, Выпуск 1.0
(продолжение с предыдущей страницы)
5
namespace
DesignPatterns\Creational\SimpleFactory;
6 7
class
Bicycle
8
{
9
public function driveTo
(string
$destination
)
10
{
11
}
12
}
Usage
1
$factory = new SimpleFactory();
2
$bicycle = $factory->createBicycle();
3
$bicycle->driveTo('Paris');
Тест
Tests/SimpleFactoryTest.php
1
2 3
declare
(strict_types
=
1
);
4 5
namespace
DesignPatterns\Creational\SimpleFactory\Tests;
6 7
use
DesignPatterns\Creational\SimpleFactory\Bicycle;
8
use
DesignPatterns\Creational\SimpleFactory\SimpleFactory;
9
use
PHPUnit\Framework\TestCase;
10 11
class
SimpleFactoryTest extends
TestCase
12
{
13
public function testCanCreateBicycle
()
14
{
15
$bicycle
=
(
new
SimpleFactory())
->
createBicycle
();
16
$this
->
assertInstanceOf
(Bicycle
::
class
,
$bicycle
);
17
}
18
}
1.1.7 Одиночка (Singleton)
Это считается анти-паттерном! Для лучшей тестируемости и сопровождения кода исполь- зуйте Инъекцию Зависимости (Dependency Injection)!
1.1. Порождающие шаблоны проектирования (Creational)
27

DesignPatternsPHP Documentation, Выпуск 1.0
Назначение
Позволяет содержать только один экземпляр объекта в приложении, которое будет обрабатывать все обращения, запрещая создавать новый экземпляр.
Примеры
• DB Connector для подключения к базе данных
• Logger
• Блокировка файла в приложении (есть только один в файловой системе с одновременным досту- пом к нему)
Диаграмма UML
Код
Вы можете найти этот код на
GitHub
Singleton.php
1
2 3
declare
(strict_types
=
1
);
4 5
namespace
DesignPatterns\Creational\Singleton;
6 7
use
Exception;
8 9
final class
Singleton
10
{
11
private static
?
Singleton
$instance
=
null
;
12 13
/**
14
* gets the instance via lazy initialization (created on first usage)
15
*/
16
public static function getInstance
()
:
Singleton
17
{
18
if
(self
::
$instance
===
null
) {
19
self
::
$instance
=
new self();
(continues on next page)
28
Глава 1. Паттерны

DesignPatternsPHP Documentation, Выпуск 1.0
(продолжение с предыдущей страницы)
20
}
21 22
return self
::
$instance
;
23
}
24 25
/**
26
* is not allowed to call from outside to prevent from creating multiple instances,
27
* to use the singleton, you have to obtain the instance from

˓→
Singleton::getInstance() instead
28
*/
29
private function
__construct
()
30
{
31
}
32 33
/**
34
* prevent the instance from being cloned (which would create a second instance of

˓→
it)
35
*/
36
private function
__clone
()
37
{
38
}
39 40
/**
41
* prevent from being unserialized (which would create a second instance of it)
42
*/
43
public function
__wakeup
()
44
{
45
throw new
Exception(
"Cannot unserialize singleton"
);
46
}
47
}
Тест
Tests/SingletonTest.php
1
2 3
declare
(strict_types
=
1
);
4 5
namespace
DesignPatterns\Creational\Singleton\Tests;
6 7
use
DesignPatterns\Creational\Singleton\Singleton;
8
use
PHPUnit\Framework\TestCase;
9 10
class
SingletonTest extends
TestCase
11
{
12
public function testUniqueness
()
13
{
14
$firstCall
=
Singleton
::
getInstance
();
15
$secondCall
=
Singleton
::
getInstance
();
16
(continues on next page)
1.1. Порождающие шаблоны проектирования (Creational)
29

DesignPatternsPHP Documentation, Выпуск 1.0
(продолжение с предыдущей страницы)
17
$this
->
assertInstanceOf
(Singleton
::
class
,
$firstCall
);
18
$this
->
assertSame
(
$firstCall
,
$secondCall
);
19
}
20
}
1.1.8 Статическая Фабрика (Static Factory)
Назначение
Подобно AbstractFactory, этот паттерн используется для создания ряда связанных или зависимых объ- ектов. Разница между этим шаблоном и Абстрактной Фабрикой заключается в том, что Статическая
Фабрика использует только один статический метод, чтобы создать все допустимые типы объектов.
Этот метод, обычно, называется factory или build.
Диаграмма UML
30
Глава 1. Паттерны

DesignPatternsPHP Documentation, Выпуск 1.0
Код
Вы можете найти этот код на
GitHub
StaticFactory.php
1
2 3
declare
(strict_types
=
1
);
4 5
namespace
DesignPatterns\Creational\StaticFactory;
6 7
use
InvalidArgumentException;
8 9
/**
10
* Note1: Remember, static means global state which is evil because it can't be mocked

˓→
for tests
11
* Note2: Cannot be subclassed or mock-upped or have multiple different instances.
12
*/
13
final class
StaticFactory
14
{
15
public static function factory
(string
$type
)
:
Formatter
16
{
17
return match
(
$type
) {
18
'number'
=>
new
FormatNumber(),
19
'string'
=>
new
FormatString(),
20
default
=>
throw new
InvalidArgumentException(
'Unknown format given'
),
21
};
22
}
23
}
Formatter.php
1
2 3
declare
(strict_types
=
1
);
4 5
namespace
DesignPatterns\Creational\StaticFactory;
6 7
interface
Formatter
8
{
9
public function format
(string
$input
)
:
string;
10
}
FormatString.php
1
2 3
declare
(strict_types
=
1
);
4 5
namespace
DesignPatterns\Creational\StaticFactory;
6 7
class
FormatString implements
Formatter
8
{
(continues on next page)
1.1. Порождающие шаблоны проектирования (Creational)
31

DesignPatternsPHP Documentation, Выпуск 1.0
(продолжение с предыдущей страницы)
9
public function format
(string
$input
)
:
string
10
{
11
return
$input
;
12
}
13
}
FormatNumber.php
1
2 3
declare
(strict_types
=
1
);
4 5
namespace
DesignPatterns\Creational\StaticFactory;
6 7
class
FormatNumber implements
Formatter
8
{
9
public function format
(string
$input
)
:
string
10
{
11
return number_format
((int)
$input
);
12
}
13
}
Тест
Tests/StaticFactoryTest.php
1
2 3
declare
(strict_types
=
1
);
4 5
namespace
DesignPatterns\Creational\StaticFactory\Tests;
6 7
use
InvalidArgumentException;
8
use
DesignPatterns\Creational\StaticFactory\FormatNumber;
9
use
DesignPatterns\Creational\StaticFactory\FormatString;
10
use
DesignPatterns\Creational\StaticFactory\StaticFactory;
11
use
PHPUnit\Framework\TestCase;
12 13
class
StaticFactoryTest extends
TestCase
14
{
15
public function testCanCreateNumberFormatter
()
16
{
17
$this
->
assertInstanceOf
(FormatNumber
::
class
, StaticFactory
::
factory
(
'number'
));
18
}
19 20
public function testCanCreateStringFormatter
()
21
{
22
$this
->
assertInstanceOf
(FormatString
::
class
, StaticFactory
::
factory
(
'string'
));
23
}
24 25
public function testException
()
(continues on next page)
32
Глава 1. Паттерны

DesignPatternsPHP Documentation, Выпуск 1.0
(продолжение с предыдущей страницы)
26
{
27
$this
->
expectException
(InvalidArgumentException
::
class
);
28 29
StaticFactory
::
factory
(
'object'
);
30
}
31
}
1.2 Структурные шаблоны проектирования (Structural)
При разработке программного обеспечения, Структурные шаблоны проектирования упрощают проек- тирование путем выявления простого способа реализовать отношения между субъектами.
1.2.1 Адаптер (Adapter / Wrapper)
Назначение
Привести нестандартный или неудобный интерфейс какого-то класса в интерфейс, совместимый с вашим кодом. Адаптер позволяет классам работать вместе стандартным образом, что обычно не полу- чается из-за несовместимых интерфейсов, предоставляя для этого прослойку с интерфейсом, удобным для клиентов, самостоятельно используя оригинальный интерфейс.
Примеры
• Адаптер клиентских библиотек для работы с базами данных
• нормализовать данные нескольких различных веб-сервисов, в одинаковую структуру, как будто вы работаете со стандартным сервисом (например при работе с API соцсетей)
1.2. Структурные шаблоны проектирования (Structural)
33

DesignPatternsPHP Documentation, Выпуск 1.0
Диаграмма UML
Код
Вы можете найти этот код на
GitHub
Book.php
1
2 3
declare
(strict_types
=
1
);
4 5
namespace
DesignPatterns\Structural\Adapter;
6 7
interface
Book
8
{
9
public function turnPage
();
10 11
public function open
();
12 13
public function getPage
()
:
int;
14
}
PaperBook.php
34
Глава 1. Паттерны

DesignPatternsPHP Documentation, Выпуск 1.0 1
2 3
declare
(strict_types
=
1
);
4 5
namespace
DesignPatterns\Structural\Adapter;
6 7
class
PaperBook implements
Book
8
{
9
private int
$page
;
10 11
public function open
()
:
void
12
{
13
$this
->
page
=
1
;
14
}
15 16
public function turnPage
()
:
void
17
{
18
$this
->
page
++
;
19
}
20 21
public function getPage
()
:
int
22
{
23
return
$this
->
page
;
24
}
25
}
EBook.php
1
2 3
declare
(strict_types
=
1
);
4 5
namespace
DesignPatterns\Structural\Adapter;
6 7
interface
EBook
8
{
9
public function unlock
();
10 11
public function pressNext
();
12 13
/**
14
* returns current page and total number of pages, like [10, 100] is page 10 of 100 15
*
16
* @return int[]
17
*/
18
public function getPage
()
:
array
;
19
}
EBookAdapter.php
1
2 3
declare
(strict_types
=
1
);
(continues on next page)
1.2. Структурные шаблоны проектирования (Structural)
35

DesignPatternsPHP Documentation, Выпуск 1.0
(продолжение с предыдущей страницы)
4 5
namespace
DesignPatterns\Structural\Adapter;
6 7
/**
8
* This is the adapter here. Notice it implements Book,
9
* therefore you don't have to change the code of the client which is using a Book
10
*/
11
class
EBookAdapter implements
Book
12
{
13
public function
__construct
(
protected
EBook
$eBook
)
14
{
15
}
16 17
/**
18
* This class makes the proper translation from one interface to another.
19
*/
20
public function open
()
21
{
22
$this
->
eBook
->
unlock
();
23
}
24 25
public function turnPage
()
26
{
27
$this
->
eBook
->
pressNext
();
28
}
29 30
/**
31
* notice the adapted behavior here: EBook::getPage() will return two integers, but

˓→
Book
32
* supports only a current page getter, so we adapt the behavior here
33
*/
34
public function getPage
()
:
int
35
{
36
return
$this
->
eBook
->
getPage
()[
0
];
37
}
38
}
Kindle.php
1
2 3
declare
(strict_types
=
1
);
4 5
namespace
DesignPatterns\Structural\Adapter;
6 7
/**
8
* this is the adapted class. In production code, this could be a class from another

˓→
package, some vendor code.
9
* Notice that it uses another naming scheme and the implementation does something

˓→
similar but in another way
10
*/
11
class
Kindle implements
EBook
(continues on next page)
36
Глава 1. Паттерны

DesignPatternsPHP Documentation, Выпуск 1.0
(продолжение с предыдущей страницы)
12
{
13
private int
$page
=
1
;
14
private int
$totalPages
=
100
;
15 16
public function pressNext
()
17
{
18
$this
->
page
++
;
19
}
20 21
public function unlock
()
22
{
23
}
24 25
/**
26
* returns current page and total number of pages, like [10, 100] is page 10 of 100 27
*
28
* @return int[]
29
*/
30
public function getPage
()
:
array
31
{
32
return
[
$this
->
page
,
$this
->
totalPages
];
33
}
34
}
Тест
Tests/AdapterTest.php
1
2 3
declare
(strict_types
=
1
);
4 5
namespace
DesignPatterns\Structural\Adapter\Tests;
6 7
use
DesignPatterns\Structural\Adapter\PaperBook;
8
use
DesignPatterns\Structural\Adapter\EBookAdapter;
9
use
DesignPatterns\Structural\Adapter\Kindle;
10
use
PHPUnit\Framework\TestCase;
11 12
class
AdapterTest extends
TestCase
13
{
14
public function testCanTurnPageOnBook
()
15
{
16
$book
=
new
PaperBook();
17
$book
->
open
();
18
$book
->
turnPage
();
19 20
$this
->
assertSame
(
2
,
$book
->
getPage
());
21
}
22 23
public function testCanTurnPageOnKindleLikeInANormalBook
()
(continues on next page)
1.2. Структурные шаблоны проектирования (Structural)
37

DesignPatternsPHP Documentation, Выпуск 1.0
(продолжение с предыдущей страницы)
24
{
25
$kindle
=
new
Kindle();
26
$book
=
new
EBookAdapter(
$kindle
);
27 28
$book
->
open
();
29
$book
->
turnPage
();
30 31
$this
->
assertSame
(
2
,
$book
->
getPage
());
32
}
33
}
1.2.2 Мост (Bridge)
Назначение
Отделить абстракцию от её реализации так, что они могут изменяться независимо друг от друга.
38
Глава 1. Паттерны

DesignPatternsPHP Documentation, Выпуск 1.0
Диаграмма UML
1.2. Структурные шаблоны проектирования (Structural)
39

DesignPatternsPHP Documentation, Выпуск 1.0
Код
Вы можете найти этот код на
GitHub
Formatter.php
1
2 3
declare
(strict_types
=
1
);
4 5
namespace
DesignPatterns\Structural\Bridge;
6 7
interface
Formatter
8
{
9
public function format
(string
$text
)
:
string;
10
}
PlainTextFormatter.php
1
2 3
declare
(strict_types
=
1
);
4 5
namespace
DesignPatterns\Structural\Bridge;
6 7
class
PlainTextFormatter implements
Formatter
8
{
9
public function format
(string
$text
)
:
string
10
{
11
return
$text
;
12
}
13
}
HtmlFormatter.php
1
2 3
declare
(strict_types
=
1
);
4 5
namespace
DesignPatterns\Structural\Bridge;
6 7
class
HtmlFormatter implements
Formatter
8
{
9
public function format
(string
$text
)
:
string
10
{
11
return sprintf
(
'
%s
'
,
$text
);
12
}
13
}
Service.php
1
2 3
declare
(strict_types
=
1
);
(continues on next page)
40
Глава 1. Паттерны

DesignPatternsPHP Documentation, Выпуск 1.0
(продолжение с предыдущей страницы)
4 5
namespace
DesignPatterns\Structural\Bridge;
6 7
abstract class
Service
8
{
9
public function
__construct
(
protected
Formatter
$implementation
)
10
{
11
}
12 13
final public function setImplementation
(Formatter
$printer
)
14
{
15
$this
->
implementation
=
$printer
;
16
}
17 18
abstract public function get
()
:
string;
19
}
HelloWorldService.php
1
2 3
declare
(strict_types
=
1
);
4 5
namespace
DesignPatterns\Structural\Bridge;
6 7
class
HelloWorldService extends
Service
8
{
9
public function get
()
:
string
10
{
11
return
$this
->
implementation
->
format
(
'Hello World'
);
12
}
13
}
PingService.php
1
2 3
declare
(strict_types
=
1
);
4 5
namespace
DesignPatterns\Structural\Bridge;
6 7
class
PingService extends
Service
8
{
9
public function get
()
:
string
10
{
11
return
$this
->
implementation
->
format
(
'pong'
);
12
}
13
}
1.2. Структурные шаблоны проектирования (Structural)
41

DesignPatternsPHP Documentation, Выпуск 1.0
Тест
Tests/BridgeTest.php
1
2 3
declare
(strict_types
=
1
);
4 5
namespace
DesignPatterns\Structural\Bridge\Tests;
6 7
use
DesignPatterns\Structural\Bridge\HelloWorldService;
8
use
DesignPatterns\Structural\Bridge\HtmlFormatter;
9
use
DesignPatterns\Structural\Bridge\PlainTextFormatter;
10
use
PHPUnit\Framework\TestCase;
11 12
class
BridgeTest extends
TestCase
13
{
14
public function testCanPrintUsingThePlainTextFormatter
()
15
{
16
$service
=
new
HelloWorldService(
new
PlainTextFormatter());
17 18
$this
->
assertSame
(
'Hello World'
,
$service
->
get
());
19
}
20 21
public function testCanPrintUsingTheHtmlFormatter
()
22
{
23
$service
=
new
HelloWorldService(
new
HtmlFormatter());
24 25
$this
->
assertSame
(
'
Hello World
'
,
$service
->
get
());
26
}
27
}
1.2.3 Компоновщик (Composite)
Назначение
Взаимодействие с иерархической группой объектов также, как и с отдельно взятым экземпляром.
42
Глава 1. Паттерны

DesignPatternsPHP Documentation, Выпуск 1.0
Примеры
• Экземпляр класса Form обрабатывает все свои элементы формы, как будто это один экземпляр.
И когда вызывается метод render(), он перебирает все дочерние элементы и вызывает их соб- ственный render().
Диаграмма UML
Код
Вы можете найти этот код на
GitHub
Renderable.php
1
2 3
declare
(strict_types
=
1
);
4 5
namespace
DesignPatterns\Structural\Composite;
6 7
interface
Renderable
8
{
9
public function render
()
:
string;
10
}
Form.php
1
2 3
declare
(strict_types
=
1
);
4 5
namespace
DesignPatterns\Structural\Composite;
6 7
/**
(continues on next page)
1.2. Структурные шаблоны проектирования (Structural)
43

DesignPatternsPHP Documentation, Выпуск 1.0
(продолжение с предыдущей страницы)
8
* The composite node MUST extend the component contract. This is mandatory for building
9
* a tree of components.
10
*/
11
class
Form implements
Renderable
12
{
13
/**
14
* @var Renderable[]
15
*/
16
private array
$elements
;
17 18
/**
19
* runs through all elements and calls render() on them, then returns the complete

˓→
representation
20
* of the form.
21
*
22
* from the outside, one will not see this and the form will act like a single

˓→
object instance
23
*/
24
public function render
()
:
string
25
{
26
$formCode
=
'
'
;
27 28
foreach
(
$this
->
elements as
$element
) {
29
$formCode
.=
$element
->
render
();
30
}
31 32
return
$formCode
'
'
;
33
}
34 35
public function addElement
(Renderable
$element
)
36
{
37
$this
->
elements
[]
=
$element
;
38
}
39
}
InputElement.php
1
2 3
declare
(strict_types
=
1
);
4 5
namespace
DesignPatterns\Structural\Composite;
6 7
class
InputElement implements
Renderable
8
{
9
public function render
()
:
string
10
{
11
return
'
  1   2   3   4   5   6   7   8   9


написать администратору сайта