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中OR与|| AND与&amp;&amp;的区别总结
Oct 26 PHP
PHP基本语法总结
Sep 06 PHP
php实现最简单的MVC框架实例教程
Sep 08 PHP
php 5.6版本中编写一个PHP扩展的简单示例
Jan 20 PHP
PHP的Yii框架中创建视图和渲染视图的方法详解
Mar 29 PHP
PHP中PDO的事务处理分析
Apr 07 PHP
PHP使用pear实现mail发送功能 windows环境下配置pear
Apr 15 PHP
在Thinkphp中使用ajax实现无刷新分页的方法
Oct 25 PHP
CI框架中类的自动加载问题分析
Nov 21 PHP
PHP下 Mongodb 连接远程数据库的实例代码
Aug 30 PHP
php 使用mpdf实现指定字段配置字体样式的方法
Jul 29 PHP
Laravel 对某一列进行筛选然后求和sum()的例子
Oct 10 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截取后台登陆密码的代码
2012/05/05 PHP
PHP获取当前文件的父目录方法汇总
2016/07/21 PHP
PHP自定义多进制的方法
2016/11/03 PHP
javascript Prototype 对象扩展
2009/05/15 Javascript
11款基于Javascript的文件管理器
2009/10/25 Javascript
jquery.validate使用攻略 第三部
2010/07/01 Javascript
基于jQuery试卷自动排版系统
2010/07/18 Javascript
js Function类型
2011/12/04 Javascript
jquery插件实现鼠标经过图片右侧显示大图的效果(类似淘宝)
2013/02/04 Javascript
jQuery获取(选中)单选,复选框,下拉框中的值
2014/02/21 Javascript
jquery插件validation实现验证身份证号等
2015/06/04 Javascript
整理Javascript事件响应学习笔记
2015/12/02 Javascript
Javascript小技能总结(推荐)
2016/06/02 Javascript
Bootstrap整体框架之CSS12栅格系统
2016/12/15 Javascript
bootstrap 设置checkbox部分选中效果
2017/04/20 Javascript
jQuery导航条固定定位效果实例代码
2017/05/26 jQuery
基于JavaScript实现图片连播和联级菜单实例代码
2017/07/28 Javascript
浅谈Vue-cli单文件组件引入less,sass,css样式的不同方法
2018/03/13 Javascript
js canvas实现橡皮擦效果
2018/12/20 Javascript
举例讲解Python中is和id的用法
2015/04/03 Python
Python从MP3文件获取id3的方法
2015/06/15 Python
PyCharm代码整体缩进,反向缩进的方法
2018/06/25 Python
python3.6 tkinter实现屏保小程序
2019/07/30 Python
python集成开发环境配置(pycharm)
2020/02/14 Python
Python Selenium实现无可视化界面过程解析
2020/08/25 Python
高校生生产实习自我鉴定
2013/09/21 职场文书
大四毕业生学习总结的自我评价
2013/10/31 职场文书
领导视察欢迎词
2014/01/15 职场文书
《世界多美呀》教学反思
2014/03/02 职场文书
焦裕禄精神心得体会
2014/09/02 职场文书
2014党员整改措施思想汇报
2014/10/07 职场文书
五一晚会主持词
2015/07/01 职场文书
2016新年问候语大全
2015/11/11 职场文书
浙江省杭州市平均工资标准是多少?
2019/07/09 职场文书
Python实战之疫苗研发情况可视化
2021/05/18 Python
CSS三大特性继承性、层叠性和优先级详解
2022/01/18 HTML / CSS