Concept
Use prototype instances to specify the types of objects to be created, and create new objects by copying these prototypes.
Prototype prototype pattern is a creational design pattern. Prototype pattern allows one object to create another customizable object without knowing any details of how to create it.
How it works
By passing a prototype object to the object to be created, the object to be created is created by requesting the prototype object to copy itself.
What problem does it solve
The main problem it faces is: the creation of "some objects with complex structures"; due to changes in requirements, these objects often face drastic changes, but they have relatively stable and consistent interfaces .
Role
Abstract prototype (Prototype) role: declares an interface for cloning itself
Concrete Prototype (Concrete Prototype) role: implements an operation of cloning itself
structure diagram
code
shallow copy mode
Copy directly, copying the reference address of the source object, etc., so the original content changes and the new content changes.
<?php header('Content-type:text/html;charset=utf-8'); /** * PHP原型模式-潜拷贝 */ /** * Interface Prototype 抽象原型模式 */ interface Prototype { // 定义拷贝自身方法啊 public function copy(); } /** * Class ConcretePrototype 具体原型模式 */ class ConcretePrototype implements Prototype { private $name; public function __construct($name) { $this->name = $name; } public function setName($name) { $this->name=$name; } public function getName() { return $this->name; } /** * 拷贝自身 * * @return ConcretePrototype 返回自身 */ public function copy() { return clone $this;//浅拷贝 } } /** * 测试潜拷贝 */ class LatentCopyDemo{ public $array; } /** * Class Client 客户端 */ class Client{ /** * 测试方法 */ public static function test(){ $demo = new LatentCopyDemo(); $demo->array = array(1,2); $object1 = new ConcretePrototype($demo); $object2 = $object1->copy(); var_dump($object1->getName()); echo '<br/>'; var_dump($object2->getName()); echo '<br/>'; $demo->array = array(3, 4); var_dump($object1->getName()); echo '<br />'; var_dump($object2->getName()); echo '<br />'; } } Client::test();
Running results
object(LatentCopyDemo)#1 (1) { ["array"]=> array(2) { [0]=> int(1) [1]=> int(2) } } object(LatentCopyDemo)#1 (1) { ["array"]=> array(2) { [0]=> int(1) [1]=> int(2) } } object(LatentCopyDemo)#1 (1) { ["array"]=> array(2) { [0]=> int(3) [1]=> int(4) } } object(LatentCopyDemo)#1 (1) { ["array"]=> array(2) { [0]=> int(3) [1]=> int(4) } }
Deep copy mode
Deep copy completes the copy through serialization and deserialization, and the content of the new copy completely copies the original content. The original content changes, but the new content remains unchanged.
<?php header('Content-type:text/html;charset=utf-8'); /** * PHP原型模式-深拷贝 */ /** * Interface Prototype 抽象原型模式 */ interface Prototype { // 定义拷贝自身方法啊 public function copy(); } /** * Class ConcretePrototype 具体原型模式 */ class ConcretePrototype implements Prototype { private $name; public function __construct($name) { $this->name = $name; } public function setName($name) { $this->name = $name; } public function getName() { return $this->name; } /** * 拷贝自身 * * @return ConcretePrototype 返回自身 */ public function copy() { $serialize_obj = serialize($this); $clone_obj = unserialize($serialize_obj); return $clone_obj; } } /** * 测试潜拷贝 */ class DeepCopyDemo{ public $array; } /** * Class Client 客户端 */ class Client{ /** * 测试方法 */ public static function test(){ $demo = new DeepCopyDemo(); $demo->array = array(1,2); $object1 = new ConcretePrototype($demo); $object2 = $object1->copy(); var_dump($object1->getName()); echo '<br/>'; var_dump($object2->getName()); echo '<br/>'; $demo->array = array(3, 4); var_dump($object1->getName()); echo '<br />'; var_dump($object2->getName()); echo '<br />'; } } Client::test();
Running results
object(DeepCopyDemo)#1 (1) { ["array"]=> array(2) { [0]=> int(1) [1]=> int(2) } } object(DeepCopyDemo)#4 (1) { ["array"]=> array(2) { [0]=> int(1) [1]=> int(2) } } object(DeepCopyDemo)#1 (1) { ["array"]=> array(2) { [0]=> int(3) [1]=> int(4) } } object(DeepCopyDemo)#4 (1) { ["array"]=> array(2) { [0]=> int(1) [1]=> int(2) } }
Advantages and disadvantages
Advantages
1. You can add and delete products at runtime
2. You can change the value to specify a new object
3. You can change the structure to specify a new object
4. Reduce the construction of subclasses
5. Use classes to dynamically configure applications
Disadvantages
The main disadvantage of the Prototype pattern is that each class must be equipped with a clone method. Moreover, this cloning method requires comprehensive consideration of the functions of the class. This is not difficult for a brand-new class, but it is not necessarily easy to transform an existing class.
Applicable scenarios
Use the Prototype pattern when a system should be created, composed and represented independently of its products
When the class to be instantiated is specified at runtime, such as dynamic loading
To avoid creating a When the factory class hierarchy is equal to the product class hierarchy;
When an instance of a class can only have one of several different state combinations. It may be more convenient to create a corresponding number of prototypes and clone them than to manually instantiate the class with the appropriate state each time