Das Prototype Design Pattern

Einführung: Eine spezielle Art des Php Design Pattern ist die Verwendung eines prototypischen Objektes und die Vervielfältigung dieses Prototypes. Für die Erzeugung des Prototypes verwenden wir den DI Container Pimple.

Ausgehend von meinen Erläuterungen zur Verwendung des DI Container Pimple beginne ich mit der Erstellung eines Factory Pattern mit Hilfe des DI Container Pimple. Für unser Beispiel verwenden wir als Stammklasse die Klasse 'Car'.

<?php

namespace models;

/**
* Erstellen eines Car und deren Nutzung als Php Design Pattern
*
* @author Stephan Krauß
* @copyright Stephan Krauss
* @lisence Stephan Krauß
* @date 26.06.2016
*
* @package models
*/

class Car extends \models\ModelData
{

}

Diese Klasse wurde als Standardklasse des Framework Frink2 geschaffen. Durch die Erweiterung der Klasse 'Car' mit dem Standard Model 'ModelData' haben wir die Methoden '__construct()' , 'getAllData()' und 'setAllData()' zur Verfügung. Gleichzeitig können wir die SPL Möglichkeiten von ArrayAccess nutzen.

class ModelData implements \ArrayAccess
{
    use \traits\arrayAccess;

    public $data = [];
    protected $pimple;

    /**
     * ModelData constructor.
     *
     * @param $pimple
     */
    public function __construct(\Pimple\Container $pimple)
    {
        $this->pimple = $pimple;
    }

    /**
     * @return array
     */
    public function getAllData()
    {
        return $this->data;
    }

    /**
     * @param array $data
     * @return ModelData
     */
    public function setAllData(array $data)
    {
        $this->data = $data;

        return $this;
    }
}

Die Methoden von ArrayAccess sind im Trait 'arrayAccess' definiert.

trait arrayAccess
{
    /**
     * @param $offset
     * @param $value
     */
    public function offsetSet($offset, $value)
    {
        if(is_null($offset)){
            $this->data[]=$value;
        } else{
            $this->data[$offset]=$value;
        }
    }

    /**
     * @param $offset
     *
     * @return bool
     */
    public function offsetExists($offset)
    {
        return isset($this->data[$offset]);
    }

    /**
     * @param $offset
     */
    public function offsetUnset($offset)
    {
        unset($this->data[$offset]);
    }

    /**
     * @param $offset
     *
     * @return null
     */
    public function offsetGet($offset)
    {
        return isset($this->data[$offset]) ? $this->data[$offset] : null;
    }
}

Sie finden diese Skripte unter github.com/StephanKrauss/frink.

__construct() des Controller

// anlegen des Model Car als Factory Pattern, kann im __construct() erfolgen
$pimple = new \Pimple\Container();

$pimple['car'] = $this->pimple->factory(function ($pimple) {
    return new \models\Car($pimple);
});

$this->pimple = $pimple;

Action des Controller

// abrufen des Model aus dem DI Container Pimple
// und PhpStorm das Model mitteilen

/** @var $modelCar \models\Car */
$modelCar = $this->pimple['car'];

// befüllen des Model 'Car' mit den Eigenschaften des Prototypes
$modelCar['engine'] = 'VW Diesel 2.0';
$modelCar['gas'] = 'diesel';
$modelCar['color'] = 'blau';
$modelCar['logo'] = 'Fußball-EM 2016';

// überprüfen des Prototype
var_dump($modelCar->getAllData());

// ergibt folgendes Ergebnis
// array (size=4)
  // 'engine' => string 'VW Diesel 2.0' (length=13)
  // 'gas' => string 'diesel' (length=6)
  // 'color' => string 'blau' (length=4)
  // 'logo' => string 'Fussball 2016' (length=13)

// erstellen einer Kleinserie aus dem Prototype
// und abstellen der produzierten Fahrzeuge
$parkplatz = [];

for($i=1; $i < 10; $i++) {
    $parkplatz[$i] = clone $modelCar;
}

Zusammenfassung:

Durch die konsequente Nutzung des DI Container kann die Erstellung der Erzeugungspatter in Php extrem vereinfacht werden. Alle modernen Frameworks verfügen über einen DI Container. Die Weitergabe der effektiven Nutzung dieser DI ist ein lohnendes Gesprächsthema im wöchentlichen Kreativfrühstück.