php设计模式小结


Posted in PHP onFebruary 15, 2013

1、单例模式

所谓单例模式,也就是在任何时候,应用程序中只会有这个类的一个实例存在。常见的,我们用到单例模式只让一个对象去访问数据库,从而防止打开多个数据库连接。要实现一个单例类应包括以下几点:

和普通类不同,单例类不能被直接实例化,只能是由自身实例化。因此,要获得这样的限制效果,构造函数必须标记为private。
要让单例类不被直接实例化而能起到作用,就必须为其提供这样的一个实例。因此,就必须要让单例类拥有一个能保存类的实例的私有静态成员变量和对应的一个能访问到实例的公共静态方法。
在PHP中,为防止对单例类对象的克隆来打破单例类的上述实现形式,通常还为基提供一个空的私有__clone()方法。
下面是一个基本的单例模式:

class SingetonBasic {
    private static $instance;
    // other vars..
    private function __construct() {
        // do construct..
    }
    private function __clone() {}
    public static function getInstance() {
        if (!(self::$instance instanceof self)) {
            self::$instance = new self();
        }
        return self::$instance;
    }
    // other functions..
}
$a = SingetonBasic::getInstance();
$b = SingetonBasic::getInstance();
var_dump($a === $b);

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

class FactoryBasic {
    public static function create($config) {
    }
}

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

// 定义形状的公共功能:获取周长和面积。
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->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、观察者模式
观察者模式为您提供了避免组件之间紧密耦合的另一种方法。该模式非常简单:一个对象通过添加一个方法(该方法允许另一个对象,即观察者注册自己)使本身变得可观察。当可观察的对象更改时,它会将消息发送到已注册的观察者。这些观察者使用该信息执行的操作与可观察的对象无关。结果是对象可以相互对话,而不必了解原因。

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

// 观察者接口
interface IObserver {
    function onListen($sender, $args);
    function getName();
}
// 可被观察接口
interface IObservable {
    function addObserver($observer);
    function removeObserver($observer_name);
}
// 观察者类
abstract class Observer implements IObserver {
    protected $name;
    public function getName() {
        return $this->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.<br/>';
    }
}
// 模拟另外一个观察者类
class OtherObserver extends Observer {
    protected $name = 'other';
    public function onListen($sender, $args) {
        echo 'other observer..<br/>';
    }
}
$rs = new RadioStation();
// 注入观察者
$rs->addObserver(new RadioStationLogger());
$rs->addObserver(new OtherObserver());
// 移除观察者
$rs->removeObserver('other');
// 可以看到观察到的信息
$rs->addListener('cctv');
PHP 相关文章推荐
php类
Nov 27 PHP
使用PHP数组实现无限分类,不使用数据库,不使用递归.
Dec 09 PHP
介绍php设计模式中的工厂模式
Jun 12 PHP
php excel类 phpExcel使用方法介绍
Aug 21 PHP
Discuz Uchome ajaxpost小技巧
Jan 04 PHP
PHP常用技巧总结(附函数代码)
Feb 04 PHP
PHP资源管理框架Assetic简介
Jun 12 PHP
PHP使用pear实现mail发送功能 windows环境下配置pear
Apr 15 PHP
使用php从身份证号中获取一系列线索(星座、生肖、生日等)
May 11 PHP
PHP针对字符串开头和结尾的判断方法
Jul 11 PHP
微信公众平台开发教程②微信端分享功能图文详解
Apr 10 PHP
PHP使用Redis队列执行定时任务实例讲解
Mar 24 PHP
php安全开发 添加随机字符串验证,防止伪造跨站请求
Feb 14 #PHP
PHP下使用CURL方式POST数据至API接口的代码
Feb 14 #PHP
PHP中通过HTTP_USER_AGENT判断是否为手机移动终端的函数代码
Feb 14 #PHP
PHP-redis中文文档介绍
Feb 07 #PHP
php中使用redis队列操作实例代码
Feb 07 #PHP
无需重新编译php加入ftp扩展的解决方法
Feb 07 #PHP
php实现utf-8和GB2312编码相互转换函数代码
Feb 07 #PHP
You might like
php中文字母数字验证码实现代码
2008/04/25 PHP
深入eAccelerator与memcached的区别详解
2013/06/06 PHP
php开启与关闭错误提示适用于没有修改php.ini的权限
2014/10/16 PHP
Codeigniter检测表单post数据的方法
2015/03/21 PHP
PHP7标量类型declare用法实例分析
2016/09/26 PHP
基于jquery的划词搜索实现(备忘)
2010/09/14 Javascript
js 模式窗口(模式对话框和非模式对话框)的使用介绍
2014/07/17 Javascript
jquery判断浏览器后退时候弹出消息的方法
2014/08/11 Javascript
AngularJS手动表单验证
2016/02/01 Javascript
JQuery PHP图片在线裁剪实例
2020/07/27 Javascript
Bootstrap超大屏幕的实现代码
2017/03/22 Javascript
Django+Vue跨域环境配置详解
2018/07/06 Javascript
原生JS实现获取及修改CSS样式的方法
2018/09/04 Javascript
从零开始用electron手撸一个截屏工具的示例代码
2018/10/10 Javascript
vue 进阶之实现父子组件间的传值
2019/04/26 Javascript
JavaScrip数组去重操作实例小结
2019/06/20 Javascript
Python多进程同步Lock、Semaphore、Event实例
2014/11/21 Python
Python字符串格式化
2015/06/15 Python
python实现生命游戏的示例代码(Game of Life)
2018/01/24 Python
Python 数据可视化pyecharts的使用详解
2019/06/26 Python
Django框架序列化与反序列化操作详解
2019/11/01 Python
Python并发请求下限制QPS(每秒查询率)的实现代码
2020/06/05 Python
如何解决pycharm调试报错的问题
2020/08/06 Python
微软美国官方网站:Microsoft美国
2018/05/10 全球购物
ANINE BING官方网站:奢华的衣橱基本款和时尚永恒的单品
2019/11/26 全球购物
药品质量检测应届生求职信
2013/11/14 职场文书
初中生学习生活的自我评价
2013/11/20 职场文书
会计系个人求职信范文分享
2013/12/20 职场文书
《七颗钻石》教学反思
2014/02/28 职场文书
2014年计生协会工作总结
2014/11/21 职场文书
招商银行收入证明
2015/06/17 职场文书
任命书格式模板
2015/09/22 职场文书
PostGIS的安装与入门使用指南
2022/01/18 PostgreSQL
MySQL 中如何归档数据的实现方法
2022/03/16 SQL Server
SpringBoot全局异常处理方案分享
2022/05/25 Java/Android
SQL Server数据库的三种创建方法汇总
2023/05/08 MySQL