Prototype 模式-極簡範例

在未開始 Prototype 設計模式前,要先理解類別中 __clone() 方法的使用。

abstract class CloneMe
{
    public $name;
    public $age;
    abstract function __clone();
}

class Person extends CloneMe
{
    public function __construct()
    {
        $this->name = "ben";
        $this->age = 39;
    }   
    
    public function display()
    {
        echo $this->name."=>".$this->age."<br />";
    }
    
    public function __clone()
    {
        echo "hi.<br />";
    }
}

$worker = new Person();
$worker->display();

$slacker = clone $worker;  //如果有__clone()方法會執行,但不能呼叫該方法
$slacker->name = "smalldl";
$slacker->age = 32;
$slacker->display();

Browser結果
ben=>39
hi.
smalldl=>32

注意:如果類別中有自行撰寫 __clone() 方法,當 clone 時會自動執行該方法,但不能直接用實例化後的物件呼叫該方法,也可以想像成 __clone() 方法是 clone 時的 __construct() 建構式方法。

Prototype 設計模式使用一種複製技術來複製已經實例化的物件,經由複製原型實例來建立新的物件。
首先建立一個抽象類,宣告變數及一個抽象 __clone() 方法。

abstract class MotoProto
{
    public $brand;
    public $speed;
    public $color;
    abstract function __clone();
}

class Honda extends MotoProto
{
    public function __construct()
    {
        $this->brand = "Honda";
        $this->speed = 180;
        $this->color = "red";
    }
    
    public function __clone(){}
}

class Toyota extends MotoProto
{
    public function __construct()
    {
        $this->brand = "Toyota";
        $this->speed = 190;
        $this->color = "white";
    }
    
    public function __clone(){}
}

建立一個 Client 類,裡面包含了原始的物件和 Clone 化的物件參考。

class Client
{
    public $honda;
    public $toyota;
    
    public $honda2;
    public $toyota2;
    
    private $car;
    
    public function __construct()
    {
        $this->honda = new Honda();
        $this->toyota = new Toyota();
        
        $this->honda2 = clone $this->honda;
        $this->toyota2 = clone $this->toyota;
        
        $this->honda2->speed = 220;
        $this->honda2->color = "black";
        
        $this->toyota2->speed = 230;
        $this->toyota2->color = "yellow";
    }
    
    public function display($car)
    {
        $this->car = $car;
        echo $this->car->brand."<br />";
        echo $this->car->speed."<br />";
        echo $this->car->color."<br />";       
    }
    
    public function show()
    {
        $this->display($this->honda);
        $this->display($this->toyota);
        echo "========clone========="."<br />";
        $this->display($this->honda2);
        $this->display($this->toyota2);
    }
}

執行

$worker = new Client();
$worker->show();

Browser結果
Honda
180
red
Toyota
190
white
========clone=========
Honda
220
black
Toyota
230
yellow