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中使用灵巧的体系结构
Oct 09 PHP
PHP分页函数代码(简单实用型)
Dec 02 PHP
让Nginx支持ThinkPHP的URL重写和PATHINFO的方法分享
Aug 08 PHP
详解PHP内置访问资源的超时时间 time_out file_get_contents read_file
Jun 03 PHP
PHP连接MySQL查询结果中文显示乱码解决方法
Oct 25 PHP
PDO防注入原理分析以及注意事项
Feb 25 PHP
PHP开发框架laravel安装与配置教程
Mar 13 PHP
微信开发之网页授权获取用户信息(二)
Jan 08 PHP
PHP查询大量数据内存耗尽问题的解决方法
Oct 28 PHP
YII2 实现多语言配置的方法分享
Jan 11 PHP
PHP数字前补0的自带函数sprintf 和number_format的用法(详解)
Feb 06 PHP
Thinkphp自定义生成缩略图尺寸的方法
Aug 05 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 接口问题(php接口主要也就是运用curl,curl函数)
2013/07/01 PHP
php实现给图片加灰色半透明效果的方法
2014/10/20 PHP
PHP中$_SERVER使用说明
2015/07/05 PHP
日常整理PHP中简单的图形处理(经典)
2015/10/26 PHP
javascript 计算两个整数的百分比值
2009/12/26 Javascript
JavaScript var声明变量背后的原理示例解析
2013/10/12 Javascript
js取消单选按钮选中示例代码
2013/11/14 Javascript
jQuery学习笔记之创建DOM元素
2015/01/19 Javascript
JavaScript实现的背景自动变色代码
2015/10/17 Javascript
移动端横屏的JS代码(beta)
2016/05/16 Javascript
AngularJS表单详解及示例代码
2016/08/17 Javascript
基于node.js的fs核心模块读写文件操作(实例讲解)
2017/09/10 Javascript
Angular实现的敏感文字自动过滤与提示功能示例
2017/12/29 Javascript
JavaScript中Object基础内部方法图
2018/02/05 Javascript
js操作二进制数据方法
2018/03/03 Javascript
node.js中TCP Socket多进程间的消息推送示例详解
2018/07/10 Javascript
Node.js的进程管理的深入理解
2019/01/09 Javascript
npm 语义版本控制详解
2019/09/10 Javascript
python通过imaplib模块读取gmail里邮件的方法
2015/05/08 Python
Python字符串替换实例分析
2015/05/11 Python
Django 多语言教程的实现(i18n)
2018/07/07 Python
Lands’ End官网:经典的美国生活方式品牌
2016/08/14 全球购物
美国祛痘、抗衰老药妆品牌:Murad
2016/08/27 全球购物
几道PHP的面试题
2012/05/19 面试题
某公司.Net方向面试题
2014/04/24 面试题
外贸业务员岗位职责
2013/11/24 职场文书
员工工作表现评语
2014/04/26 职场文书
铣床操作工岗位职责
2014/06/13 职场文书
五月的鲜花活动方案
2014/08/21 职场文书
民主评议政风行风整改方案
2014/09/17 职场文书
融资合作协议书范本
2014/10/17 职场文书
合法的离婚协议书范本
2014/10/23 职场文书
优秀团支部申报材料
2014/12/26 职场文书
Nginx快速入门教程
2021/03/31 Servers
centos环境下nginx高可用集群的搭建指南
2022/07/23 Servers
HTML页面点击按钮关闭页面的多种方式
2022/12/24 HTML / CSS