本文实例讲述了php中常用的三种设计模式。分享给大家供大家参考,具体如下:
php中常用的三种设计模式:单例模式、工厂模式、观察者模式
1.单例模式
为何要使用php单例模式?
多数人都是从单例模式的字面上的意思来理解它的用途, 认为这是对系统资源的节省, 可以避免重复实例化, 是一种”计划生育”. 而php每次执行完页面都是会从内存中清理掉所有的资源. 因而php中的单例实际每次运行都是需要重新实例化的, 这样就失去了单例重复实例化的意义了. 单单从这个方面来说, php的单例的确有点让各位失望. 但是单例仅仅只有这个功能和应用吗? 答案是否定的。
php的应用主要在于数据库应用, 所以一个应用中会存在大量的数据库操作, 在使用面向对象的方式开发时(废话), 如果使用单例模式, 则可以避免大量的new 操作消耗的资源。如果系统中需要有一个类来全局控制某些配置信息, 那么使用单例模式可以很方便的实现. 这个可以参看zend framework的frontcontroller部分。在一次页面请求中, 便于进行调试, 因为所有的代码(例如数据库操作类db)都集中在一个类中, 我们可以在类中设置钩子, 输出日志,从而避免到处var_dump, echo。一个单例类应包括以下几点:
和普通类不同,单例类不能被直接实例化,只能是由自身实例化。因此,要获得这样的限制效果,构造函数必须标记为private。
要让单例类不被直接实例化而能起到作用,就必须为其提供这样的一个实例。因此,就必须要让单例类拥有一个能保存类的实例的私有静态成员变量和对应的一个能访问到实例的公共静态方法。
在php中,为防止对单例类对象的克隆来打破单例类的上述实现形式,通常还为其提供一个空的私有__clone()
方法。
对于一个类的对象,如果使用“clone运算符”,就会复制出一个和当前对象完全一样的新对象出来,并且,此时还会自动调用该类的魔术方法:__clone()
(只要该类中有该方法)。
则要实现单例类,就应该对这个单例类的对象“禁止克隆”,用private来修饰__clone()来实现禁止克隆,具体可参考。
单例模式的例子:
<?php/*** 设计模式之单例模式* $instance必须声明为静态的私有变量* 构造函数和析构函数必须声明为私有,防止外部程序new* 类从而失去单例模式的意义* getinstance()方法必须设置为公有的,必须调用此方法* 以返回实例的一个引用* ::操作符只能访问静态变量和静态函数* new对象都会消耗内存* 使用场景:最常用的地方是数据库连接。* 使用单例模式生成一个对象后,* 该对象可以被其它众多对象所使用。*/class singetonbasic {private static $instance; //静态变量要私有化,防止类外修改// other vars..private function __construct() { //构造函数私有化,类外不能直接新建对象 // do construct..}private function 怎样保护眼睛__clone() {} //在__clone()前用private修饰,用来禁止克隆public static function getinstance() { //公共的静态方法,public——外部的接口,static——不使用对象而是通过类名访问 if (!(lf::$instance instanceof lf)) { //私有静态变量$instance为空 lf::$instance = new lf(); //新建为自身的对象,并赋值给私有变量$instance } return lf::$instance; //返回私有变量$instance}// other functions..}$a = singetonbasic::getinstance();$b = singetonbasic::getinstance();var_dump($a === $b); //结果为:boolean true//?>
<?php/** * php单例,单例模式为何只能实例化一次*/class example{ // 保存类实例在此属性中 private static $instance; // 构造方法声明为private,防止直接创建对象 private function __construct(){ echo 'i am constructed'; } // singleton 方法 public static function singleton(){ if (!ist(lf::$instance)) {生日对自己说的话//判断是否以前创建了当前类的实例 $c = __class__;//获取类名 lf::$instance = new $c;//如果没有创建,实例化当前类,这里实现类只实例化一次 } return lf::$instance;//返回类的实例 } // example类中的普通方法 public function bark(){ echo 'woof!'; } // 阻止用户复制对象实例 public function __clone(){ trigger_error('clone is not allowed.', e_ur_error); }}// 这个写法会出错,因为构造方法被声明为private$test = new example;// 下面将得到example类的单例对象$test = example::singleton();$test->bark();// 下面将得到example类的单例对象$test = example::singleton();$test->bark();// 复制对象将导致一个e_ur_error.$test_clone = clone $test;?>
关于__clone()
方法可参考: php对象克隆__clone()介绍
2. 工厂模式
工厂模式在于可以根据输入参数或者应用程序配置的不同来创建一种专门用来实现化并返回其它类的实例的类。
工厂模式的例子:
<?phpclass factorybasic { public static function create($config) { }}
比如这里是一个描述形状对象的工厂,它希望根据传入的参数个数不同来创建不同的形状。
<?php// 定义形状的公共功能:获取周长和面积。interface ishape { function getcircum(); function getarea();}// 定义矩形类class rectangle implements ishape { private $width, $height; public function __construct($width, $height) { $this->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->ra少儿围棋dii; } public function getarea() { return m_pi * pow($this->radii, 2); }}// 根据传入的参数个数不同来创建不同的形状。class factoryshape { public static function create() { switch (func_num_args()) { ca 1: return new circle(func_get_arg(0)); break; ca 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. 观察者模式
观察者模式为您提供了避免组件之间紧密耦合的另一种方法。该模式非常简单:一个对象通过添加一个方法(该方法允许另一个对象,即观察者注册自己)使本身变得可观察。当可观察的对象更改时,它会将消息发送到已注册的观察者。这些观察者使用该信息执行的操作与可观察的对象无关。结果是对象可以相互对话,而不必了解原因。
一个简单的示例:当听众在收听电台时(即电台加入一个新听众),它将发送出一条提示消息,通过发送消息的日志观察者可以观察这些消息。
<?php// 观察者接口interface iobrver { function onlisten($nder, $args); function getname();}// 可被观察接口interface iobrvable { function addobrver($obrver); function removeobrver($obrver_name);}// 观察者类abstract class obrver implements iobrver { protected $name; public function getname() { return $this->name; }}// 可被观察类class obrvable implements iobrvable { protected $obrvers = array(); public function addobrver($obrver) { if (!($obrver instanceof iobrver)) { return; } $this->obrvers[] = $obrver; } public function removeobrver($obrv手机广告语er_name) { foreach ($this->obrvers as $index => $obrver) { if ($obrver->getname() === $obrver_name) { array_splice($this->obrvers, $index, 1); return; } } }}// 模拟一个可以被观察的类:radiostationclass radiostation extends obrvable { public function addlistener($listener) { foreach ($this->obrvers as $obrver) { $obrver->onlisten($this, $listener); } }}// 模拟一个观察者类class radiostationlogger extends obrver { protected $name = 'logger'; public function onlisten($nder, $args) { echo $args, ' join the radiostation.<br/>'; }}// 模拟另外一个观察者类class otherobrver extends obrver { protected $name = 'other'; public function onlisten($nder, $args) { echo 'other obrver..<br/>'; }}$rs = new radiostation();// 注入观察者$rs->addobrver(new radiostationlogger());$rs->addobrver(new otherobrver());// 移除观察者$rs->removeobrver('other');// 可以看到观察到的信息$rs->addlistener('cctv');?>
更多关于php相关内容感兴趣的读者可查看本站专题:《php面向对象程序设计入门教程》、《php数组(array)操作技巧大全》、《php基本语法入门教程》、《php运算与运算符用法总结》、《php字符串(string)用法总结》、《php+mysql数据库操作入门教程》及《php常见数据库操作技巧汇总》
希望本文所述对大家php程序设计有所帮助。
本文发布于:2023-04-07 07:52:07,感谢您对本站的认可!
本文链接:https://www.wtabcd.cn/fanwen/zuowen/b95d153015c0d7af5a6be5cef8c4aeb0.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文word下载地址:PHP中常用的三种设计模式详解【单例模式、工厂模式、观察者模式】.doc
本文 PDF 下载地址:PHP中常用的三种设计模式详解【单例模式、工厂模式、观察者模式】.pdf
留言与评论(共有 0 条评论) |