builder pattern php

Solutions on MaxInterview for builder pattern php by the best coders in the world

showing results for - "builder pattern php"
Alessandro
08 Sep 2017
1<?php
2
3namespace RefactoringGuru\Builder\Conceptual;
4
5/**
6 * The Builder interface specifies methods for creating the different parts of
7 * the Product objects.
8 */
9interface Builder
10{
11    public function producePartA(): void;
12
13    public function producePartB(): void;
14
15    public function producePartC(): void;
16}
17
18/**
19 * The Concrete Builder classes follow the Builder interface and provide
20 * specific implementations of the building steps. Your program may have several
21 * variations of Builders, implemented differently.
22 */
23class ConcreteBuilder1 implements Builder
24{
25    private $product;
26
27    /**
28     * A fresh builder instance should contain a blank product object, which is
29     * used in further assembly.
30     */
31    public function __construct()
32    {
33        $this->reset();
34    }
35
36    public function reset(): void
37    {
38        $this->product = new Product1();
39    }
40
41    /**
42     * All production steps work with the same product instance.
43     */
44    public function producePartA(): void
45    {
46        $this->product->parts[] = "PartA1";
47    }
48
49    public function producePartB(): void
50    {
51        $this->product->parts[] = "PartB1";
52    }
53
54    public function producePartC(): void
55    {
56        $this->product->parts[] = "PartC1";
57    }
58
59    /**
60     * Concrete Builders are supposed to provide their own methods for
61     * retrieving results. That's because various types of builders may create
62     * entirely different products that don't follow the same interface.
63     * Therefore, such methods cannot be declared in the base Builder interface
64     * (at least in a statically typed programming language). Note that PHP is a
65     * dynamically typed language and this method CAN be in the base interface.
66     * However, we won't declare it there for the sake of clarity.
67     *
68     * Usually, after returning the end result to the client, a builder instance
69     * is expected to be ready to start producing another product. That's why
70     * it's a usual practice to call the reset method at the end of the
71     * `getProduct` method body. However, this behavior is not mandatory, and
72     * you can make your builders wait for an explicit reset call from the
73     * client code before disposing of the previous result.
74     */
75    public function getProduct(): Product1
76    {
77        $result = $this->product;
78        $this->reset();
79
80        return $result;
81    }
82}
83
84/**
85 * It makes sense to use the Builder pattern only when your products are quite
86 * complex and require extensive configuration.
87 *
88 * Unlike in other creational patterns, different concrete builders can produce
89 * unrelated products. In other words, results of various builders may not
90 * always follow the same interface.
91 */
92class Product1
93{
94    public $parts = [];
95
96    public function listParts(): void
97    {
98        echo "Product parts: " . implode(', ', $this->parts) . "\n\n";
99    }
100}
101
102/**
103 * The Director is only responsible for executing the building steps in a
104 * particular sequence. It is helpful when producing products according to a
105 * specific order or configuration. Strictly speaking, the Director class is
106 * optional, since the client can control builders directly.
107 */
108class Director
109{
110    /**
111     * @var Builder
112     */
113    private $builder;
114
115    /**
116     * The Director works with any builder instance that the client code passes
117     * to it. This way, the client code may alter the final type of the newly
118     * assembled product.
119     */
120    public function setBuilder(Builder $builder): void
121    {
122        $this->builder = $builder;
123    }
124
125    /**
126     * The Director can construct several product variations using the same
127     * building steps.
128     */
129    public function buildMinimalViableProduct(): void
130    {
131        $this->builder->producePartA();
132    }
133
134    public function buildFullFeaturedProduct(): void
135    {
136        $this->builder->producePartA();
137        $this->builder->producePartB();
138        $this->builder->producePartC();
139    }
140}
141
142/**
143 * The client code creates a builder object, passes it to the director and then
144 * initiates the construction process. The end result is retrieved from the
145 * builder object.
146 */
147function clientCode(Director $director)
148{
149    $builder = new ConcreteBuilder1();
150    $director->setBuilder($builder);
151
152    echo "Standard basic product:\n";
153    $director->buildMinimalViableProduct();
154    $builder->getProduct()->listParts();
155
156    echo "Standard full featured product:\n";
157    $director->buildFullFeaturedProduct();
158    $builder->getProduct()->listParts();
159
160    // Remember, the Builder pattern can be used without a Director class.
161    echo "Custom product:\n";
162    $builder->producePartA();
163    $builder->producePartC();
164    $builder->getProduct()->listParts();
165}
166
167$director = new Director();
168clientCode($director);