PHP中有哪些常用的设计模式
创始人
2024-12-06 19:42:15
0次

1.单例模式

为何要使用PHP单例模式?

多数人都是从单例模式的字面上的意思来理解它的用途, 认为这是对系统资源的节省, 可以避免重复实例化, 是一种”计划生育”. 而PHP每次执行完页面都是会从内存中清理掉所有的资源. 因而PHP中的单例实际每次运行都是需要重新实例化的, 这样就失去了单例重复实例化的意义了. 单单从这个方面来说, PHP的单例的确有点让各位失望. 但是单例仅仅只有这个功能和应用吗? 答案是否定的。

  1. php的应用主要在于数据库应用, 所以一个应用中会存在大量的数据库操作, 在使用面向对象的方式开发时(废话), 如果使用单例模式, 则可以避免大量的new 操作消耗的资源。

  2. 如果系统中需要有一个类来全局控制某些配置信息, 那么使用单例模式可以很方便的实现. 这个可以参看zend Framework的FrontController部分。

  3. 在一次页面请求中, 便于进行调试, 因为所有的代码(例如数据库操作类db)都集中在一个类中, 我们可以在类中设置钩子, 输出日志,从而避免到处var_dump, echo。

一个单例类应包括以下几点:

和普通类不同,单例类不能被直接实例化,只能是由自身实例化。因此,要获得这样的限制效果,构造函数必须标记为private。

要让单例类不被直接实例化而能起到作用,就必须为其提供这样的一个实例。因此,就必须要让单例类拥有一个能保存类的实例的私有静态成员变量和对应的一个能访问到实例的公共静态方法。

在PHP中,为防止对单例类对象的克隆来打破单例类的上述实现形式,通常还为其提供一个空的私有__clone()方法。

对于一个类的对象,如果使用“clone运算符”,就会复制出一个和当前对象完全一样的新对象出来,并且,此时还会自动调用该类的魔术方法:__clone()(只要该类中有该方法)。

则要实现单例类,就应该对这个单例类的对象“禁止克隆”,用private来修饰__clone()来实现禁止克隆,具体可参考单例类的加强:禁止克隆。

单例模式的例子:

bark();
// 下面将得到Example类的单例对象
$test = Example::singleton();
$test->bark();
// 复制对象将导致一个E_USER_ERROR.
$test_clone = clone $test;
?>

关于__clone()方法可参考: PHP对象克隆__clone()介绍

2. 工厂模式

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

工厂模式的例子:

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

width = $width;
    $this->height = $height;
  }
  public function getCircum() {
    return 2 * ($this->width + $this->height);
  }
  public function getArea() {
    return $this->width * $this->height;
  }
}
// 定义圆类
class Circle implements IShape {
  private $radii;
  public function __construct($radii) {
    $this->radii = $radii;
  }
  public function getCircum() {
    return 2 * M_PI * $this->radii;
  }
  public function getArea() {
    return M_PI * pow($this->radii, 2);
  }
}
// 根据传入的参数个数不同来创建不同的形状。
class FactoryShape {
  public static function create() {
    switch (func_num_args()) {
      case 1:
      return new Circle(func_get_arg(0));
      break;
      case 2:
      return new Rectangle(func_get_arg(0), func_get_arg(1));
      break;
    }
  }
}
// 矩形对象
$c = FactoryShape::create(4, 2);
var_dump($c->getArea());
// 圆对象
$o = FactoryShape::create(2);
var_dump($o->getArea());

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

3. 观察者模式

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

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

name;
  }
}
// 可被观察类
class Observable implements IObservable {
  protected $observers = array();
  public function addObserver($observer) {
    if (!($observer instanceof IObserver)) {
      return;
    }
    $this->observers[] = $observer;
  }
  public function removeObserver($observer_name) {
    foreach ($this->observers as $index => $observer) {
      if ($observer->getName() === $observer_name) {
        array_splice($this->observers, $index, 1);
        return;
      }
    }
  }
}
// 模拟一个可以被观察的类:RadioStation
class RadioStation extends Observable {
  public function addListener($listener) {
    foreach ($this->observers as $observer) {
      $observer->onListen($this, $listener);
    }
  }
}
// 模拟一个观察者类
class RadioStationLogger extends Observer {
  protected $name = 'logger';
  public function onListen($sender, $args) {
    echo $args, ' join the radiostation.
';   } } // 模拟另外一个观察者类 class OtherObserver extends Observer {   protected $name = 'other';   public function onListen($sender, $args) {     echo 'other observer..
';   } } $rs = new RadioStation(); // 注入观察者 $rs->addObserver(new RadioStationLogger()); $rs->addObserver(new OtherObserver()); // 移除观察者 $rs->removeObserver('other'); // 可以看到观察到的信息 $rs->addListener('cctv'); ?>

相关内容

热门资讯

空调连续工作多久需要停机休息 空调连续工作的时间取决于多个因素,包括空调的型号、功率、使用环境和维护情况等。一般来说,空调可以连续...
空调哪个符号是除湿的 空调除湿功能通常用一个水滴形状的符号表示。不同品牌和型号的空调遥控器可能会有所差异,但一般来说,除湿...
格力空调多长时间加一次氟利昂 1、一般情况下,空调对氟利昂的使用量是非常小的,所以在空调使用了四年左右的时候再考虑加也没问题。2、...
空调用多长时间需要加氟一次 一般情况下是五年。当出现以下这几种情况时,空调才需要加氟。1、空调的室内机和室外机各有两个接口,当接...
格调生活·C标思享荟:卡萨帝在... 9月12日的郑州龙湖金融岛,夜风轻拂,灯光璀璨。“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑...
品牌价值破千亿、高端份额持续领... 9月12日,“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑州站”在郑州龙湖金融岛举办。2026...
空调主板坏了修800还是换新的 空调主板坏了是修还是换新,需要考虑多个因素,以下是一些建议:1. 维修成本:如果维修费用较低,比如 ...
空调开多久需要休息多长时间 问题:空调开多久需要休息多长时间回答:1、在使用空调的过程中,一般空调开7~8个小时左右需要休息2~...
中央空调多长时间清洗一次 1、一般空调开机前清洗一次即可,空调开机中间时段再清洗一次,空调关机时清洗一次,这样比较合理。2、空...
中央空调氟利昂多久加一次 看空调制热和制冷程度,很多人的观点认为氟利昂必须一年放一次,其实这个观点是错误的,理解上面有点偏差,...