欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  后端开发

php常用的三种设计模式的学习笔记

程序员文章站 2022-05-17 19:38:01
...
  1. class SingetonBasic {

  2. private static $instance;
  3. // other vars..

  4. private function __construct() {

  5. // do construct..
  6. }
  7. private function __clone() {}

  8. public static function getInstance() {

  9. if (!(self::$instance instanceof self)) {
  10. self::$instance = new self();
  11. }
  12. return self::$instance;
  13. }
  14. // other functions..

  15. }
  16. $a = SingetonBasic::getInstance();

  17. $b = SingetonBasic::getInstance();
  18. var_dump($a === $b);
复制代码

二、工厂模式 工厂模式在于可以根据输入参数或者应用程序配置的不同来创建一种专门用来实现化并返回其它类的实例的类。 工厂模式的例子:

  1. class FactoryBasic {

  2. public static function create($config) {
  3. }

  4. }
复制代码

比如这里是一个描述形状对象的工厂,它希望根据传入的参数个数不同来创建不同的形状。

  1. // 定义形状的公共功能:获取周长和面积。

  2. interface IShape {
  3. function getCircum();
  4. function getArea();
  5. }
  6. // 定义矩形类

  7. class Rectangle implements IShape {
  8. private $width, $height;
  9. public function __construct($width, $height) {

  10. $this->width = $width;
  11. $this->height = $height;
  12. }
  13. public function getCircum() {

  14. return 2 * ($this->width + $this->height);
  15. }
  16. public function getArea() {

  17. return $this->width * $this->height;
  18. }
  19. }
  20. // 定义圆类

  21. class Circle implements IShape {
  22. private $radii;
  23. public function __construct($radii) {

  24. $this->radii = $radii;
  25. }
  26. public function getCircum() {

  27. return 2 * M_PI * $this->radii;
  28. }
  29. public function getArea() {

  30. return M_PI * pow($this->radii, 2);
  31. }
  32. }
  33. // 根据传入的参数个数不同来创建不同的形状。

  34. class FactoryShape {
  35. public static function create() {
  36. switch (func_num_args()) {
  37. case 1:
  38. return new Circle(func_get_arg(0));
  39. break;
  40. case 2:
  41. return new Rectangle(func_get_arg(0), func_get_arg(1));
  42. break;
  43. }

  44. }
  45. }
  46. // 矩形对象

  47. $c = FactoryShape::create(4, 2);
  48. var_dump($c->getArea());
  49. // 圆对象
  50. $o = FactoryShape::create(2);
  51. var_dump($o->getArea());
复制代码

使用工厂模式使得在调用方法时变得更容易,因为它只有一个类和一个方法,若没有使用工厂模式,则要在调用时决定应该调用哪个类和哪个方法;使用工厂模式还使得未来对应用程序做改变时更加容易,比如要增加一种形状的支持,只需要修改工厂类中的create()一个方法,而没有使用工厂模式,则要修改调用形状的代码块。

三、观察者模式 观察者模式为您提供了避免组件之间紧密耦合的另一种方法。该模式非常简单:一个对象通过添加一个方法(该方法允许另一个对象,即观察者注册自己)使本身变得可观察。当可观察的对象更改时,它会将消息发送到已注册的观察者。这些观察者使用该信息执行的操作与可观察的对象无关。结果是对象可以相互对话,而不必了解原因。

一个简单的示例:当听众在收听电台时(即电台加入一个新听众),它将发送出一条提示消息,通过发送消息的日志观察者可以观察这些消息。

  1. // 观察者接口

  2. interface IObserver {
  3. function onListen($sender, $args);
  4. function getName();
  5. }
  6. // 可被观察接口

  7. interface IObservable {
  8. function addObserver($observer);
  9. function removeObserver($observer_name);
  10. }
  11. // 观察者类

  12. abstract class Observer implements IObserver {
  13. protected $name;
  14. public function getName() {

  15. return $this->name;
  16. }
  17. }
  18. // 可被观察类

  19. class Observable implements IObservable {
  20. protected $observers = array();
  21. public function addObserver($observer) {

  22. if (!($observer instanceof IObserver)) {
  23. return;
  24. }
  25. $this->observers[] = $observer;
  26. }
  27. public function removeObserver($observer_name) {

  28. foreach ($this->observers as $index => $observer) {
  29. if ($observer->getName() === $observer_name) {
  30. array_splice($this->observers, $index, 1);
  31. return;
  32. }
  33. }
  34. }
  35. }
  36. // 模拟一个可以被观察的类:RadioStation

  37. class RadioStation extends Observable {
  38. public function addListener($listener) {

  39. foreach ($this->observers as $observer) {
  40. $observer->onListen($this, $listener);
  41. }
  42. }
  43. }
  44. // 模拟一个观察者类

  45. class RadioStationLogger extends Observer {
  46. protected $name = 'logger';
  47. public function onListen($sender, $args) {

  48. echo $args, ' join the radiostation.
    ';
  49. }
  50. }
  51. // 模拟另外一个观察者类

  52. class OtherObserver extends Observer {
  53. protected $name = 'other';
  54. public function onListen($sender, $args) {
  55. echo 'other observer..
    ';
  56. }
  57. }
  58. $rs = new RadioStation();

  59. // 注入观察者

  60. $rs->addObserver(new RadioStationLogger());
  61. $rs->addObserver(new OtherObserver());
  62. // 移除观察者

  63. $rs->removeObserver('other');
  64. // 可以看到观察到的信息

  65. $rs->addListener('cctv');
  66. ?>
复制代码