Creational/Builder
This commit is contained in:
parent
ab4499a305
commit
979ae42cde
@ -2,9 +2,7 @@
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
use PhpCsFixer\Config;
|
||||
use PhpCsFixer\Finder;
|
||||
use PhpCsFixer\Runner\Parallel\ParallelConfigFactory;
|
||||
use PhpCsFixer\{Config, Finder, Runner\Parallel\ParallelConfigFactory};
|
||||
|
||||
$finder = (new Finder())->in([
|
||||
__DIR__ . '/src',
|
||||
|
43
code/builder.php
Normal file
43
code/builder.php
Normal file
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package: patterns
|
||||
* @author: Yevhen Odynets
|
||||
* @date: 2025-07-04
|
||||
* @time: 00:19
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
use Pattern\Creational\Builder\BigMacBuilder;
|
||||
use Pattern\Creational\Builder\Director;
|
||||
|
||||
/**
|
||||
* The client code creates a builder object, passes it to the director and then
|
||||
* initiates the construction process. The end result is retrieved from the
|
||||
* builder object.
|
||||
*
|
||||
* @noinspection ForgottenDebugOutputInspection*/
|
||||
function clientCode(Director $director): void
|
||||
{
|
||||
$builder = new BigMacBuilder();
|
||||
$director->setBuilder($builder);
|
||||
|
||||
echo 'Preparing full featured Big Mac...';
|
||||
$director->regularBigMac();
|
||||
dump($builder->getBigMac()->getIngredients());
|
||||
|
||||
echo 'Preparing vegan Big Mac...';
|
||||
$director->veganBigMac();
|
||||
dump($builder->getBigMac()->getIngredients());
|
||||
|
||||
// The Builder pattern can be used without a Director class.
|
||||
echo 'Preparing a custom snack...';
|
||||
$builder->produceBun();
|
||||
$builder->produceMeat();
|
||||
$builder->produceSauce();
|
||||
dump($builder->getBigMac()->getIngredients());
|
||||
}
|
||||
|
||||
|
||||
clientCode(new Director());
|
40
src/Pattern/Creational/Builder/BigMac.php
Normal file
40
src/Pattern/Creational/Builder/BigMac.php
Normal file
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package: patterns
|
||||
* @author: Yevhen Odynets
|
||||
* @date: 2025-07-04
|
||||
* @time: 00:21
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace Pattern\Creational\Builder;
|
||||
|
||||
class BigMac
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private array $ingredients = [];
|
||||
|
||||
/**
|
||||
* @param string $ingredient
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setIngredient(string $ingredient): static
|
||||
{
|
||||
$this->ingredients[] = $ingredient;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getIngredients(): array
|
||||
{
|
||||
return $this->ingredients;
|
||||
}
|
||||
}
|
118
src/Pattern/Creational/Builder/BigMacBuilder.php
Normal file
118
src/Pattern/Creational/Builder/BigMacBuilder.php
Normal file
@ -0,0 +1,118 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package: patterns
|
||||
* @author: Yevhen Odynets
|
||||
* @date: 2025-07-04
|
||||
* @time: 00:42
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace Pattern\Creational\Builder;
|
||||
|
||||
/**
|
||||
* The BigMac Builder classes follow the BigMacBuilderInterface interface and provide
|
||||
* specific implementations of the building steps. The program may have several
|
||||
* variations of BigMac Builders, implemented differently.
|
||||
*/
|
||||
class BigMacBuilder implements BigMacBuilderInterface
|
||||
{
|
||||
private BigMac $bigMac;
|
||||
|
||||
/**
|
||||
* A fresh builder instance should contain a blank BigMac object, which is
|
||||
* used in further assembly.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->reset();
|
||||
}
|
||||
|
||||
public function reset(): void
|
||||
{
|
||||
$this->bigMac = new BigMac();
|
||||
}
|
||||
|
||||
/**
|
||||
* All production steps work with the same BigMac instance.
|
||||
*/
|
||||
public function produceBun(): void
|
||||
{
|
||||
$this->bigMac->setIngredient('A three-slice sesame seed bun');
|
||||
}
|
||||
|
||||
public function produceVeganBun(): void
|
||||
{
|
||||
$this->bigMac->setIngredient('A three-slice dairy-free bun');
|
||||
}
|
||||
|
||||
public function produceMeat(): void
|
||||
{
|
||||
$this->bigMac->setIngredient('Two 1.6 oz beef patties');
|
||||
}
|
||||
|
||||
public function produceVeganMeat(): void
|
||||
{
|
||||
$this->bigMac->setIngredient('Two plant-based burgers, like Impossible Burgers or Pureland Farm Burgers');
|
||||
}
|
||||
|
||||
public function produceSauce(): void
|
||||
{
|
||||
$this->bigMac->setIngredient('"special sauce" (similar to Thousand Island dressing)');
|
||||
}
|
||||
|
||||
public function produceVeganSauce(): void
|
||||
{
|
||||
$this->bigMac->setIngredient('Vegan special sauce');
|
||||
}
|
||||
|
||||
public function produceLettuce(): void
|
||||
{
|
||||
$this->bigMac->setIngredient('Shredded iceberg lettuce');
|
||||
}
|
||||
|
||||
public function produceCheese(): void
|
||||
{
|
||||
$this->bigMac->setIngredient('One slice of processed American cheese');
|
||||
}
|
||||
|
||||
public function produceVeganCheese(): void
|
||||
{
|
||||
$this->bigMac->setIngredient('One slice of vegan American or cheddar cheese');
|
||||
}
|
||||
|
||||
public function producePickles(): void
|
||||
{
|
||||
$this->bigMac->setIngredient('Two dill pickle slices');
|
||||
}
|
||||
|
||||
public function produceOnions(): void
|
||||
{
|
||||
$this->bigMac->setIngredient('Minced onions');
|
||||
}
|
||||
|
||||
/**
|
||||
* MigMac Builders are supposed to provide their own methods for
|
||||
* retrieving results. That's because various types of builders may create
|
||||
* entirely different BigMacs that don't follow the same interface.
|
||||
* Therefore, such methods cannot be declared in the base Builder interface
|
||||
* (at least in a statically typed programming language). Note that PHP is a
|
||||
* dynamically typed language and this method CAN be in the base interface.
|
||||
* However, we won't declare it there for the sake of clarity.
|
||||
*
|
||||
* Usually, after returning the end result to the client, a builder instance
|
||||
* is expected to be ready to start producing another BigMac. That's why
|
||||
* it's a usual practice to call the reset method at the end of the
|
||||
* `getBigMac` method body. However, this behavior is not mandatory, and
|
||||
* you can make your builders wait for an explicit reset call from the
|
||||
* client code before disposing of the previous result.
|
||||
*/
|
||||
public function getBigMac(): BigMac
|
||||
{
|
||||
$result = $this->bigMac;
|
||||
$this->reset();
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
41
src/Pattern/Creational/Builder/BigMacBuilderInterface.php
Normal file
41
src/Pattern/Creational/Builder/BigMacBuilderInterface.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package: patterns
|
||||
* @author: Yevhen Odynets
|
||||
* @date: 2025-07-04
|
||||
* @time: 00:32
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace Pattern\Creational\Builder;
|
||||
|
||||
/**
|
||||
* The BigMacBuilderInterface specifies methods for creating the different parts of
|
||||
* the BigMac objects.
|
||||
*/
|
||||
interface BigMacBuilderInterface
|
||||
{
|
||||
public function produceBun(): void;
|
||||
|
||||
public function produceVeganBun(): void;
|
||||
|
||||
public function produceMeat(): void;
|
||||
|
||||
public function produceVeganMeat(): void;
|
||||
|
||||
public function produceSauce(): void;
|
||||
|
||||
public function produceVeganSauce(): void;
|
||||
|
||||
public function produceLettuce(): void;
|
||||
|
||||
public function produceCheese(): void;
|
||||
|
||||
public function produceVeganCheese(): void;
|
||||
|
||||
public function producePickles(): void;
|
||||
|
||||
public function produceOnions(): void;
|
||||
}
|
62
src/Pattern/Creational/Builder/Director.php
Normal file
62
src/Pattern/Creational/Builder/Director.php
Normal file
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package: patterns
|
||||
* @author: Yevhen Odynets
|
||||
* @date: 2025-07-04
|
||||
* @time: 01:49
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace Pattern\Creational\Builder;
|
||||
|
||||
/**
|
||||
* The Director is only responsible for executing the building steps in a
|
||||
* particular sequence. It is helpful when producing Big Macs according to a
|
||||
* specific order or configuration. Strictly speaking, the Director class is
|
||||
* optional, since the client can control builders directly.
|
||||
*/
|
||||
class Director
|
||||
{
|
||||
/**
|
||||
* @var BigMacBuilder
|
||||
*/
|
||||
private BigMacBuilder $builder;
|
||||
|
||||
/**
|
||||
* The Director works with any builder instance that the client code passes
|
||||
* to it. This way, the client code may alter the final type of the newly
|
||||
* assembled product.
|
||||
*/
|
||||
public function setBuilder(BigMacBuilder $builder): void
|
||||
{
|
||||
$this->builder = $builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* The Director can construct several product variations using the same
|
||||
* building steps.
|
||||
*/
|
||||
public function regularBigMac(): void
|
||||
{
|
||||
$this->builder->produceBun();
|
||||
$this->builder->produceMeat();
|
||||
$this->builder->produceSauce();
|
||||
$this->builder->produceLettuce();
|
||||
$this->builder->produceCheese();
|
||||
$this->builder->producePickles();
|
||||
$this->builder->produceOnions();
|
||||
}
|
||||
|
||||
public function veganBigMac(): void
|
||||
{
|
||||
$this->builder->produceVeganBun();
|
||||
$this->builder->produceVeganMeat();
|
||||
$this->builder->produceVeganSauce();
|
||||
$this->builder->produceLettuce();
|
||||
$this->builder->produceVeganCheese();
|
||||
$this->builder->producePickles();
|
||||
$this->builder->produceOnions();
|
||||
}
|
||||
}
|
@ -9,6 +9,8 @@
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
use Random\RandomException;
|
||||
|
||||
/**
|
||||
* @param ...$vars
|
||||
*
|
||||
@ -36,7 +38,7 @@ function trace(): string
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \Random\RandomException
|
||||
* @throws RandomException
|
||||
*/
|
||||
function getFloatRange(): float
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user