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 相关文章推荐
让你同时上传 1000 个文件 (二)
Oct 09 PHP
落伍首发 php+mysql 采用ajax技术的 省 市 地 3级联动无刷新菜单 源码
Dec 16 PHP
一个简单的PHP&amp;MYSQL留言板源码
Jul 19 PHP
IIS6的PHP最佳配置方法
Mar 19 PHP
php md5下16位和32位的实现代码
Apr 09 PHP
php array_push()数组函数:将一个或多个单元压入数组的末尾(入栈)
Jul 12 PHP
php数组函数序列之in_array() 查找数组值是否存在
Oct 29 PHP
php编写的抽奖程序中奖概率算法
May 14 PHP
php使用curl详细解析及问题汇总
Aug 11 PHP
thinkPHP数据库增删改查操作方法实例详解
Dec 06 PHP
PHP实现二维数组中的查找算法小结
Jun 09 PHP
PHP连接SQL server数据库测试脚本运行实例
Aug 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扩展程序实现守护进程
2015/04/16 PHP
PHP中$GLOBALS['HTTP_RAW_POST_DATA']和$_POST的区别分析
2017/07/03 PHP
PHP实现微信退款的方法示例
2019/03/26 PHP
js类中的公有变量和私有变量
2008/07/24 Javascript
js跨浏览器实现将字符串转化为xml对象的方法
2013/09/25 Javascript
nodejs爬虫抓取数据乱码问题总结
2015/07/03 NodeJs
详解nodejs 文本操作模块-fs模块(二)
2016/12/22 NodeJs
详解angular中如何监控dom渲染完毕
2017/01/03 Javascript
js实现悬浮窗效果(支持拖动)
2017/03/09 Javascript
php简单数据库操作类的封装
2017/06/08 Javascript
解决jquery appaend元素中id绑定事件失效的问题
2017/09/12 jQuery
node(koa2) web应用模块介绍详解
2019/03/29 Javascript
通过实例解析JavaScript常用排序算法
2020/09/02 Javascript
Python中asyncore的用法实例
2014/09/29 Python
解决python2.7用pip安装包时出现错误的问题
2017/01/23 Python
对变量赋值的理解--Pyton中让两个值互换的实现方法
2017/11/29 Python
python SSH模块登录,远程机执行shell命令实例解析
2018/01/12 Python
face++与python实现人脸识别签到(考勤)功能
2019/08/28 Python
pygame实现打字游戏
2021/02/19 Python
Python 基于wxpy库实现微信添加好友功能(简洁)
2019/11/29 Python
如何基于Python制作有道翻译小工具
2019/12/16 Python
python numpy库linspace相同间隔采样的实现
2020/02/25 Python
Python自动创建Excel并获取内容
2020/09/16 Python
CPB肌肤之钥美国官网:Clé de Peau Beauté
2017/09/05 全球购物
马来西亚网上购物:Youbeli
2018/03/30 全球购物
与世界上最好的跑步专业品牌合作:Fleet Feet
2019/03/22 全球购物
西班牙宠物用品和食品网上商店:Tiendanimal
2019/06/06 全球购物
雏鹰争章活动总结
2014/05/09 职场文书
政风行风建设责任书
2014/07/23 职场文书
“四风”问题对照检查材料思想汇报
2014/09/16 职场文书
大学生国庆节65周年演讲稿范文
2014/09/25 职场文书
领导班子“四风问题”“整改方案
2014/10/02 职场文书
检查机关党的群众路线个人整改措施
2014/10/04 职场文书
大学生学生会工作总结2015
2015/05/26 职场文书
2016参观监狱警示教育活动心得体会
2016/01/15 职场文书
Hive HQL支持2种查询语句风格
2022/06/25 数据库