PHP code example of xoubaman / builder

1. Go to this page and download the library: Download xoubaman/builder library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

xoubaman / builder example snippets


//Class to build
final class MetalSlugCharacter {
    private string $name;
    private Weapon $weapon;
    private int $bombs;

    public function __construct(string $name, Weapon $weapon, int $bombs) {...}
    public static function create(): self {}
    public function loadBombs(int $howMany): void {}
}

//The builder
final class MetalSlugCharacterBuilder extends Builder {
    //Class to instantiate, leave empty to return an array
    protected const CLASS_TO_BUILD = MetalSlugCharacter::class;
    //Constructor to use, leave empty to use the default __construct()
    protected const USE_CONSTRUCTOR = 'create';
    //Call this method after instantiation. First element is the method name, the other will be used as parameters to the call 
    protected const AFTER_BUILD_CALL = ['loadBombs', 100];

    public function __construct() {
        //This data setup will be used by default
        //It must hold enough parameters and in the same order as needed by the constructor being used
        $this->base = [
            'name'   => 'Marco Rossi',
            'weapon' => new RocketLauncher(),
            'bombs'  => fn() => rand(10, 50), //Callables will be invoked to get the value
        ];
    }

    //Tip: override build() for type hinting
    public function build(): MetalSlugCharacter {
        return parent::build();
    }

    //We declare methods to modify the build setup 
    public function withName(string $name): self {
        return $this->addToCurrent('name', $name);
    }

    public function withWeapon(Weapon $weapon): self {
        return $this->addToCurrent('weapon', $weapon);
    }
    
    //Be creative with method names to express intention and improve readability
    public function withoutWeapon(): self  {
        return $this->addToCurrent('weapon', new BareHands);
    }
}

$builder = new MetalSlugCharacterBuilder();

//A new instance with default values
$character = $builder->build(); //Returns the default Marco + Rocket Launcher

//A new instance with a different setup
$character = $builder
                ->withName('Eri Kasamoto')
                ->withWeapon(new HeavyMachineGun())
                ->build();

//A new instance with the same setup as the last one created
$character = $builder->cloneLast(); //Returns Eri with the Heavy Machine Gun again

$character = $builder->repeatLastSetup() //Repeats the Eri + Heavy Machine Gun setup
    ->withBombs(5) //Methods starting with "with" change the current setup using __call 
    ->build();

//Instead of doing all the time
$character = $builder
                ->withWeapon(new HeavyMachineGun())
                ->withBombs(99)
                ->build();

//Encapsulate concrete setups in a static factory methods
public static function fullyLoadedWithMachineGun(): MetalSlugCharacter
{
    return (new self())
                ->withWeapon(new HeavyMachineGun())
                ->withBombs(99)
                ->build();
}

public static function emptyHanded(): MetalSlugCharacter
{
    return (new self())
                ->withWeapon(new BareHands())
                ->withBombs(0)
                ->build();
}


//And start to use meaningful one liners that do not create distraction in the tests
$character = MetalSlugCharacterBuilder::fullyLoadedWithMachineGun();
$character = MetalSlugCharacterBuilder::emptyHanded();