Шаблон Builder (Строитель)
12-08-2019Время чтения ~ 2 мин.PHP/ООП 8039
На мой взгляд паттерн Builder один из самых сложных. Найти ему практическое применение проблематично, поэтому он используется только в очень редких случаях, когда требуется работать со сложным составным объектом.
Смысл Строителя в том, чтобы иметь возможность получить конечный результат в различном виде. Например есть некий «Продукт», который может быть получен разными «Строителями» (один делает одно, другой другое). И есть класс, который управляет строителями — «Директор».
Исходный рабочий код, вы всё также найдёте на гитхабе. Рекомендую вначале с ним бегло ознакомиться и держать под рукой по мере объяснений ниже. :-)
Итак, как это работает?
Есть некий продукт — класс Product. У него есть метод add() — это некое действие которое и создает сам «Продукт». В реальности там может быть множество других методов. Метод getProduct() отдает результат всех операций (готовый «Продукт»).
Так же есть «Строители» — классы ConcreteBuilder1 и ConcreteBuilder2. Оба они расширяют абстрактный класс с той целью, чтобы обеспечить единый тип данных.
«Строители» знают как создавать «Продукт». Для этого они используют методы класса Product, но каждый делает это по своему. То есть готовый «Продукт» у каждого «Строителя» будет разный. Получить результат «строительства» можно через метод getResult().
Теперь как это использовать.
Вначале создаются экземпляры «Директора» и «Строителей». У «Директора» есть метод setConstruct(), через который происходит передача конкретного «Строителя». Поскольку строители имеют один тип, то мы знаем какие у них есть методы выполнения (buildPartA, buildPartB). Это всё происходит автоматом в setConstruct().
После этого можно получить готовый продукт. Экземпляр «Продукта» возвращается через метод «Строителя» getResult() — обратите внимание, что это объект класса Product. И после этого уже получаем готовый «Продукт» через getProduct().
Странный код, зачем строителям абстрактный метод для получения результата если он в них реализован одинаково.
Абстрактный класс нужен для того, чтобы классы строителей были одного типа. В принципе можно вместо абстрактного класса использовать интерфейс. Когда у строителей один тип, то класс директора может ими манипулировать одинаково.