[关闭]
@Chiang 2019-12-12T14:30:12.000000Z 字数 4492 阅读 579

原型模式

设计模式


定义

  • 原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
  • 用于创建重复的对象,使用克隆技术来复制实例化的对象,新对象是复制原型实例创造来的
  • 使用克隆对象来减少new对象的开销
  • 原型: 是被克隆的那一个

这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式。例如,一个对象需要在一个高代价的数据库操作之后被创建。我们可以缓存该对象,在下一个请求时返回它的克隆,在需要的时候更新数据库,以此来减少数据库调用。

实现原理

  • 克隆不会调用构造函数
  • 使用克隆来创建新的对象的时候,并不能触发类的构造函数
  • 避免构造函数的强依赖

浅复制

  • 原型被改变了,克隆出来的对象也会被改变

1.创建一个键盘类

  1. <?php
  2. /**
  3. * 键盘类
  4. *
  5. * @author Luffy (lufei@swoole.com)
  6. * @date 2019/10/24
  7. * @copyright Swoole, Inc.
  8. * @package sy-records/design-patterns
  9. */
  10. namespace Luffy\DesignPatterns\Prototype;
  11. class Keyboard
  12. {
  13. /**
  14. * 键盘名称
  15. *
  16. * @var
  17. */
  18. public $name;
  19. }

2.创建一个浅复制类

  1. <?php
  2. /**
  3. * 浅复制
  4. *
  5. * @author Luffy (lufei@swoole.com)
  6. * @date 2019/10/24
  7. * @copyright Swoole, Inc.
  8. * @package sy-records/design-patterns
  9. */
  10. namespace Luffy\DesignPatterns\Prototype;
  11. class ShallowCopy
  12. {
  13. private $keyboard;
  14. public function __construct()
  15. {
  16. echo '亲爱的大哥'.PHP_EOL;
  17. }
  18. public function setKeyboard($keyboard)
  19. {
  20. $this->keyboard = $keyboard;
  21. }
  22. public function get()
  23. {
  24. echo '我想要个'.$this->keyboard->name. '的键盘' .PHP_EOL;
  25. }
  26. }

3.创建客户端实现类

  1. <?php
  2. /**
  3. * User:çlufei
  4. * Date: 2019/10/24
  5. * Email: lufei@swoole.com.
  6. */
  7. require __DIR__ . '/../vendor/autoload.php';
  8. use Luffy\DesignPatterns\Prototype\ShallowCopy;
  9. use Luffy\DesignPatterns\Prototype\Keyboard;
  10. use Luffy\DesignPatterns\Prototype\DeepCopy;
  11. class Client
  12. {
  13. /**
  14. * 浅复制
  15. */
  16. public static function shallowCopy()
  17. {
  18. $shallowCopy = new ShallowCopy();
  19. $keyboard = new Keyboard();
  20. $keyboard->name = "ikbc";
  21. $shallowCopy->setKeyboard($keyboard);
  22. $shallowCopy->get();
  23. echo "-----\n";
  24. // clone不会调用构造函数
  25. $cloneShallow = clone $shallowCopy;
  26. $cloneShallow->get();
  27. }
  28. public static function shallowCopy2()
  29. {
  30. $shallowCopy = new ShallowCopy();
  31. $keyboard = new Keyboard();
  32. $keyboard->name = "ikbc";
  33. $shallowCopy->setKeyboard($keyboard);
  34. $shallowCopy->get();
  35. echo "-----\n";
  36. // clone不会调用构造函数
  37. $cloneShallow = clone $shallowCopy;
  38. $cloneShallow->get();
  39. echo "=====\n";
  40. $keyboard->name = "hhkb";
  41. $shallowCopy->get();
  42. $cloneShallow->get();
  43. }
  44. public static function deepCopy()
  45. {
  46. $keyboard = new Keyboard();
  47. $keyboard->name = "ikbc";
  48. $deepCopy = new DeepCopy();
  49. $deepCopy->setKeyboard($keyboard);
  50. $deepCopy->get();
  51. echo "-----\n";
  52. $cloneDeep = clone $deepCopy;
  53. $cloneDeep->get();
  54. echo "=====\n";
  55. $keyboard->name = "hhkb";
  56. $deepCopy->get();
  57. $cloneDeep->get();
  58. }
  59. }
  60. Client::shallowCopy();
  61. echo "***************".PHP_EOL;
  62. Client::shallowCopy2();
  63. echo "***************".PHP_EOL;
  64. Client::deepCopy();

深复制

  • 实现了克隆的接口

1.创建一个键盘类

  1. <?php
  2. /**
  3. * 键盘类
  4. *
  5. * @author Luffy (lufei@swoole.com)
  6. * @date 2019/10/24
  7. * @copyright Swoole, Inc.
  8. * @package sy-records/design-patterns
  9. */
  10. namespace Luffy\DesignPatterns\Prototype;
  11. class Keyboard
  12. {
  13. /**
  14. * 键盘名称
  15. *
  16. * @var
  17. */
  18. public $name;
  19. }

2.创建克隆接口

  1. <?php
  2. /**
  3. * 原型模式
  4. *
  5. * @author Luffy (lufei@swoole.com)
  6. * @date 2019/10/24
  7. * @copyright Swoole, Inc.
  8. * @package sy-records/design-patterns
  9. */
  10. namespace Luffy\DesignPatterns\Prototype;
  11. interface Prototype
  12. {
  13. public function __clone();
  14. }

3.创建一个深复制实现克隆接口

  1. <?php
  2. /**
  3. * 深复制
  4. *
  5. * @author Luffy (lufei@swoole.com)
  6. * @date 2019/10/25
  7. * @copyright Swoole, Inc.
  8. * @package sy-records/design-patterns
  9. */
  10. namespace Luffy\DesignPatterns\Prototype;
  11. class DeepCopy implements Prototype
  12. {
  13. private $keyboard;
  14. public function __construct()
  15. {
  16. echo '美丽的姐姐'.PHP_EOL;
  17. }
  18. public function setKeyboard($keyboard)
  19. {
  20. $this->keyboard = $keyboard;
  21. }
  22. public function get()
  23. {
  24. echo '我想要个'.$this->keyboard->name. '的键盘' .PHP_EOL;
  25. }
  26. public function __clone()
  27. {
  28. $this->keyboard = clone $this->keyboard;
  29. }
  30. }

4.创建客户端实现类

  1. <?php
  2. /**
  3. * User:çlufei
  4. * Date: 2019/10/24
  5. * Email: lufei@swoole.com.
  6. */
  7. require __DIR__ . '/../vendor/autoload.php';
  8. use Luffy\DesignPatterns\Prototype\ShallowCopy;
  9. use Luffy\DesignPatterns\Prototype\Keyboard;
  10. use Luffy\DesignPatterns\Prototype\DeepCopy;
  11. class Client
  12. {
  13. /**
  14. * 浅复制
  15. */
  16. public static function shallowCopy()
  17. {
  18. $shallowCopy = new ShallowCopy();
  19. $keyboard = new Keyboard();
  20. $keyboard->name = "ikbc";
  21. $shallowCopy->setKeyboard($keyboard);
  22. $shallowCopy->get();
  23. echo "-----\n";
  24. // clone不会调用构造函数
  25. $cloneShallow = clone $shallowCopy;
  26. $cloneShallow->get();
  27. }
  28. public static function shallowCopy2()
  29. {
  30. $shallowCopy = new ShallowCopy();
  31. $keyboard = new Keyboard();
  32. $keyboard->name = "ikbc";
  33. $shallowCopy->setKeyboard($keyboard);
  34. $shallowCopy->get();
  35. echo "-----\n";
  36. // clone不会调用构造函数
  37. $cloneShallow = clone $shallowCopy;
  38. $cloneShallow->get();
  39. echo "=====\n";
  40. $keyboard->name = "hhkb";
  41. $shallowCopy->get();
  42. $cloneShallow->get();
  43. }
  44. public static function deepCopy()
  45. {
  46. $keyboard = new Keyboard();
  47. $keyboard->name = "ikbc";
  48. $deepCopy = new DeepCopy();
  49. $deepCopy->setKeyboard($keyboard);
  50. $deepCopy->get();
  51. echo "-----\n";
  52. $cloneDeep = clone $deepCopy;
  53. $cloneDeep->get();
  54. echo "=====\n";
  55. $keyboard->name = "hhkb";
  56. $deepCopy->get();
  57. $cloneDeep->get();
  58. }
  59. }
  60. Client::shallowCopy();
  61. echo "***************".PHP_EOL;
  62. Client::shallowCopy2();
  63. echo "***************".PHP_EOL;
  64. Client::deepCopy();

参考资料:
swoole微课堂
GitHub
https://www.runoob.com/

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注