php设计模式小结

 更新时间:2013年02月15日 16:26:26   转载 作者:  
这篇文章主要介绍php的设计模式,主要介绍以下三中模式,主要包括单例模式,工厂模式,观察者模式

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');

相关文章

  • smarty中先strip_tags过滤html标签后truncate截取文章运用

    smarty中先strip_tags过滤html标签后truncate截取文章运用

    strip_tags() 函数剥去 HTML、XML 以及 PHP 的标签。
    2010-10-10
  • 利用PHP判断是手机移动端还是PC端访问的函数示例

    利用PHP判断是手机移动端还是PC端访问的函数示例

    在平常工作开发中,我们通常需要开发出PC端和移动端两个不同的系统,从而根据访问端的不同进入到不同的操作界面中。下面这篇文章主要给大家介绍了关于利用PHP判断是手机移动端还是PC端访问的函数的相关资料,需要的朋友可以参考下。
    2017-12-12
  • php实现的SSO单点登录系统接入功能示例分析

    php实现的SSO单点登录系统接入功能示例分析

    这篇文章主要介绍了php实现的SSO单点登录系统接入功能,简单分析了SSO单点登录系统接入的原理与php相关实现技巧,需要的朋友可以参考下
    2016-10-10
  • php中spl_autoload详解

    php中spl_autoload详解

    SPL 是Standard PHP Library(标准PHP库)的缩写。它是PHP5引入的一个扩展库,其主要功能包括autoload机制的实现及包括各种Iterator接口或类。 SPL autoload机制的实现是通过将函数指针autoload_func指向自己实现的具有自动装载功能的函数来实现的。
    2014-10-10
  • PHP 模板高级篇总结

    PHP 模板高级篇总结

    PHP 模板高级篇总结...
    2006-12-12
  • php中实现xml与mysql数据相互转换的方法

    php中实现xml与mysql数据相互转换的方法

    这篇文章主要介绍了php中实现xml与mysql数据相互转换的方法,实例封装了一个类文件,可实现XML与MySQL数据的相互转换,具有一定的参考借鉴价值,需要的朋友可以参考下
    2014-12-12
  • php使用gearman进行任务分发操作实例详解

    php使用gearman进行任务分发操作实例详解

    这篇文章主要介绍了php使用gearman进行任务分发操作,结合实例形式详细分析了gearman的安装以及PHP使用gearman进行异步处理任务相关操作技巧,需要的朋友可以参考下
    2020-02-02
  • php 上传功能实例代码

    php 上传功能实例代码

    php 上传功能实例代码,需要的朋友可以参考下。
    2010-04-04
  • php使用timthumb生成缩略图的方法

    php使用timthumb生成缩略图的方法

    这篇文章主要介绍了php使用timthumb生成缩略图的方法,实例分析了PHP调用timthumb生成缩略图的操作技巧与相关注意事项,需要的朋友可以参考下
    2016-01-01
  • PHP实现文字写入图片功能

    PHP实现文字写入图片功能

    这篇文章主要为大家详细介绍了PHP实现文字写入图片功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-02-02

最新评论