200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > PHP观察者设计模式项目应用案例

PHP观察者设计模式项目应用案例

时间:2024-01-03 02:32:46

相关推荐

PHP观察者设计模式项目应用案例

php教程|php手册

PHP,观察者,设计模式,项目,应用,案例,前言,这篇,文章

php教程-php手册

网狐棋牌6.6完整源码,vscode怎么看内存地址,Ubuntu删除go,启动tomcat环境变量,褐色微小爬虫,php源文件编译,新安县seo优化哪家强lzw

前言:这篇文章讲的是 PHP (当然,语言无关紧要。要注重思想,并非实现工具)项目中,观察者设计模式的应用案例分析。这个案例中,我会和大家分享我对观察者的理解(概念),说说为什么要用观察者模式(应用场合),以及一些唠叨(扩展 )。喔,对了。本文

VHMS销售系统源码,vscode右键菜单没了,试用ubuntu 密码,tomcat挂了发邮件,爬虫背景,php 上传临时文件夹,seo问答推广外包报价,自适应式电影网站,html客服咨询界面模板lzw

ssh源码下载,一个类似vscode紫色的图标,ubuntu rm 恢复,判断tomcat访问异常就重启,sqlite 软件 排序,折纸网页设计, 实时显示服务器时间,worepress采集插件,前端框架有用,加密u盾爬虫,php链接mysql数据库,网站seo优化快速排名工具,c代码库网站,手机网页省市区,html5模板网,钓鱼页面源码,通用订单管理系统,适合新手的程序源代码lzw

前言:这篇文章讲的是PHP(当然,语言无关紧要。要注重思想,并非实现工具)项目中,观察者设计模式的应用案例分析。这个案例中,我会和大家分享我对观察者的理解(概念),说说为什么要用观察者模式(应用场合),以及一些唠叨(扩展)。喔,对了。本文所给出的代码均为示例代码,摘自项目中的部分源码,略有改动,不可直接复用。

概念:

也许,你会挺过什么“钩子”、“触发器”、“事件驱动”、“回调函数”等类似这样的名词。其实,这些思想多多少少都和我要说的观察者设计模式有关。

如果你懂Java,你会见过这样的代码(事件监听):

this.addWindowListener(this);

如果你懂Javascript,你会见过这样的代码(回调函数):

$.get(“”,function() {// code...});

如果,你既没有听过那些名词,也见过上述类似的代码。OK,我来说下观察者的思想。

很简单,无非就是当某一指定的事情发生时,程序根据预期设计好的行为予以实施。再简单点,比如有个游戏,A、B两个人。如果,A跳一下,B应该做出微笑的表情;如果,A蹲一下,B应该做出哭的表情(这个例子好无厘头啊…)。这就是,观察者思想。我想你懂了,不懂我就是B了(哭笑不得)。

解释下两个名词,观察者(Obsever)和被观察者(Obsevable)。B是观察者,A是被观察者(解释的充分吧,自己理解)。

应用场合:

l 前景提要

这时,我刚刚加入这个团队。我们的项目是一款基于微信平台的应用(当然,也有网站端)。其中的团队成员ML已经实现好了微信端的主动推送,采用的是模板消息接口(事件源是用户在发表或者参与一些我们开发好的功能的动作)。问题来了,这时老大说,我们要采用邮件推送,由我来负责。我简单问了下ML的推送机制,居然采用的过程式的写法。这导致新功能的加入不好扩展和维护。扩展指的是我的功能不好加入原来的程序,因为没有一个标准的接口供我可用;维护是指尽管我把邮件推送的功能加进去,会导致我们的代码更显冗余致使无法更新换代。

所以,我向ML提议采用观察者设计模式,达成一致。

l 代码

既然我提到了不好扩展是因为没有统一的标准,那么我们需要提供一套标准:

PushObsevable.php(被观察者接口)

/** * 推送被(可)观察者接口 * * Created by GenialX at .11.24 * */ Interface PushObservable {// 注册(添加)观察者Public function addObserver(PushObserver $pObserver);// 移除观察者Public function removeObserver(PushObserver $pObserver);// 通知观察者Public function notify();}

PushObserver(观察者接口)

/** * 推送观察者接口 * * Created by GenialX at .11.24 * */ Interface PushObserver {// 返回名称Public function getName();// 更新Public function update(); }

有了标准的接口,但是并不希望直接声明类直接实现这些接口,因为这不利实现,导致在每声明一个类继承这个接口时都需要重新写一遍一样的实现。所以,继而分别写了两个抽象类继承并实现了这些接口中的成员方法。

AbstractPushObservable(被观察者抽象类)

/** * 被观察者抽象类 * * Created by GenialX at .11.24 * */require_once PushObservable.php;Abstract Class AbstractPushObservable Implements PushObservable {Private $_observers = array(); // 观察者容器// 注册(添加)观察者Public function addObserver(PushObserver $pObserver) {if( ! isset( $this->_observers[ $pObserver->getName() ] ) ) {$this->_observers[ $pObserver->getName() ] = & $pObserver;return TRUE;}return FALSE;}// 移除观察者Public function removeObserver(PushObserver $pObserver) {if( isset( $this->_observers[ $pObserver->getName() ] ) ) {$this->_observers[ $pObserver->getName() ] = NULL;unset( $this->_observers[ $pObserver->getName() ] );return TRUE;}return FALSE;}// 获取观察者// $name 唯一标识 可取InterfacePush 常量Public function getObserver($name) {if( isset( $this->_observers[ $name ] ) ) {return $this->_observers[ $name ] ;}return FALSE;}// 通知观察者Public function notify() {foreach ( $this->_observers as $observer ) {$observer->update();}}}

AbstractPushObserver(观察者抽象类)

/** * 观察者抽象类 * * Created by GenialX at .11.24 * */require_once PushObserver.php;Abstract Class AbstractPushObserver Implements PushObserver{Private $_name; // 名称(唯一标志)Public function __construct($name = NULL) {if(is_null($name)) {$this->_name = AbstractPushObserver . rand(1000,9999);} else {$this->_name = $name;}}// 返回名称Public function getName() {return $this->_name;}// 更新Public function update() {// 重写方法...}}

有了抽象类,这时是不是可以直接声明类继承这些抽象类了呢?是的。但是,在我们的项目中并没有采用直接声明类继承这些抽象类。因为针对,微信的模板消息推送和邮件推送仍有一些公用的实现。所以,分别写了公用的实现类。

CommonPushObservable(公用推送被观察者类)

/** * 公用推送被观察者类 * * Created by GenialX at .11.24 * */require_once AbstractPushObservable.php;Class CommonPushObservable Extends AbstractPushObservable {Public function __construct() {}}

CommonPushObserver(公用推送观察者类)

/** * 公用推送观察者类 * * Created by GenialX at .11.25 * */require_once AbstractPushObserver.php;class CommonPushObserver extends AbstractPushObserver {private static $weixinUsers = array (); // 符合推送的微信用户信息private static $renrenUsers = array (); // 符合推送的人人用户信息public static $CI;Public function __construct($name = NULL) {parent::__construct ( $name );CommonPushObserver::$CI = & get_instance ();CommonPushObserver::$CI->load->library ( distance );}/**根据地理位置获取符合推送条件的用户信息 * * @param float $lon * @param float $lat * @param string $fromUser * */Public Static function getUsers($lon, $lat, $fromUser) {// ... }

这时,已经设计好了推送机制的标准。只要针对这个标准去实现不同的功能即可。这样,不必担心扩展和维护的问题。因为,有了标准。

先看下调用代码(就这么优雅):

$CPO = new CommonPushObservable(); // 实例化被观察者 $EP = new EmailPush(EmailPush::PUSH_EMAIL_OBJECT); // 实例化观察者(邮件推送观察者类,下文有代码)$WP = new WechatPush(WechatPush::PUSH_EMAIL_OBJECT); // 实例化观察者(微信消息模板观察者类)$EP->setPushType($EP::PUSH_TYPE_WISH_LIST); // 设置推送类型$EP->setPushType($WP::PUSH_TYPE_WISH_LIST); // 设置推送类型$EP->id(12)->email(genialx@)->text(Hello World!); // 设置消息体$EP->openid(‘openid’)->text(‘Hello World!’); // 设置消息体$EP->getUsers($lon, $lat, $fromUser); // 获取用户$CPO->addObserver($EP); // 注册观察者$CPO->addObserver($WP); // 注册观察者$CPO->notify(); // 通知观察者 推送微信消息和邮件消息

扩展:

1、推送类型和消息体的设置重复,那么你是否会想到封装?

2、PUSH_TYPE_WISH_LIST类似常量的存在是不是更好?

答案是肯定的!

参考文章:PHP观察者模式 /php-design-mode-observer.html

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。