• 设计模式学习系列——原型模式


    原型模式

      原型模式(Prototype Pattern),通过复制一个已存在对象来生成一个新对象,被复制的对象称为原型。

      优点:不采用new来创建对象,new会消耗较大,原型模式只需要拷贝内存即可。

      原型模式的复制又可分为两种:深拷贝和浅拷贝

      深拷贝是通过拷贝内存(包括引用的对象)实现对象的创建,不仅会拷贝类的基本类型的属性和方法,也会拷贝类中引用的其它类的对象。

      浅拷贝则会拷贝类的基本类型的属性和方法,对于引用的对象,只会拷贝引用的值。

      深拷贝可以通过将对象序列化成字节流,再反序列化来实现;浅拷贝则可直接运用clone方法(在php中)。

      角色:1)抽象原型角色;2)具体实现原型角色。

      应用场景:

      需要创建一个复杂的、构造耗时很多的对象,且已有一个同类对象的时候。

      消费者不关心对象构造过程的时候。

      如 :工作流实例的重建、复杂数据实体的复制。

      以下实例详细描述了如何使用原型模式进行深拷贝和浅拷贝,以及最后的效果如何,使用php编写。

     1 <?php
     2 /*
     3  * 原型模式示例
     4  */
     5 error_reporting(E_ALL);
     6 ini_set('display_errors','on');
     7     
     8 /*
     9  * 抽象接口类
    10  * 包括深拷贝和浅拷贝方法,使得实现它的类都可以实现
    11  */
    12  interface Prototype{
    13      public function shadowCopy();//浅拷贝
    14      public function deepCopy();//深拷贝
    15 }
    16 
    17 /*
    18  * 需要引用的对象的类Person
    19  */
    20 class Person{
    21    public $name; 
    22    public function __construct($name) {
    23        $this->name = $name;
    24    }
    25    public function getName(){
    26        return $this->name;
    27    }
    28 }
    29 
    30 /*
    31  *原型类 
    32  */
    33 class Demo implements Prototype{
    34     private $person;
    35     public function __construct($person) {
    36         $this->person = $person;
    37     }
    38     public function setPerson($person){
    39         $this->person = $person;
    40     }
    41     public function getPerson(){
    42         return $this->person;
    43     }
    44     public function shadowCopy() {
    45         return clone $this;
    46     }
    47     public function deepCopy() {
    48         $serializeObj = serialize($this);
    49         $cloneObj = unserialize($serializeObj);
    50         return $cloneObj;
    51     }
    52     private  function __clone() {
    53         echo "come here when clone";
    54     }
    55 }
    56 
    57 $person = new Person("Mary");
    58 $demoObj = new Demo($person);
    59 $shadowCopyObj = $demoObj->shadowCopy();
    60 $deepCopyObj = $demoObj->deepCopy();
    61 
    62 //复制后,原型对象,深拷贝对象,浅拷贝对象中的引用对象值一致
    63 var_dump($demoObj->getPerson()->getName()).PHP_EOL;//string(4) "Mary" 
    64 var_dump($shadowCopyObj->getPerson()->getName()).PHP_EOL;//string(4) "Mary" 
    65 var_dump($deepCopyObj->getPerson()->getName()).PHP_EOL;//string(4) "Mary" 
    66 
    67 //更改原型对象的引用对象中的值后,原型对象和浅拷贝对象因为引用地址一样都改变,深拷贝对象不变
    68 $person->name = "Jack";
    69 var_dump($demoObj->getPerson()->getName()).PHP_EOL;//string(4) "Jack" 
    70 var_dump($shadowCopyObj->getPerson()->getName()).PHP_EOL;//string(4) "Jack" 
    71 var_dump($deepCopyObj->getPerson()->getName()).PHP_EOL;//string(4) "Mary"
    72 
    73 //更换原型对象的引用对象后,原型对象再次改变,浅拷贝对象因为引用地址没有改变所以不变,深拷贝对象不受影响还是保持最开始的值
    74 $person2 = new Person("Peter");
    75 $demoObj->setPerson($person2);
    76 var_dump($demoObj->getPerson()->getName()).PHP_EOL;//string(4) "Peter" 
    77 var_dump($shadowCopyObj->getPerson()->getName()).PHP_EOL;//string(4) "Jack" 
    78 var_dump($deepCopyObj->getPerson()->getName()).PHP_EOL;//string(4) "Mary"
    79     
    80 ?>
    View Code

     

    参考文档:

    php设计模式——原型模式

    【设计模式】原型模式

  • 相关阅读:
    八、vue使用element-ui组件
    七、vue语法补充二(动态组件 & 异步组件、访问元素 & 组件、混入)
    oracle中使用sql语句生成10w条测试数据
    六、vue路由Vue Router
    五、vue状态管理模式vuex
    前端生态/工程化
    四、vue语法补充
    三、vue脚手架工具vue-cli的使用
    二、vue中组件的使用
    使用阿里云OSS上传文件
  • 原文地址:https://www.cnblogs.com/Andres/p/8953311.html
Copyright © 2020-2023  润新知