对zencart通知者观察者模式的理解

用于收藏精华贴子、网友共享的资料等。可以回复,不能发新贴。

版主: Jack

版面规则
本版面不能发新贴,可以回复

对zencart通知者观察者模式的理解

帖子xiayouqiao » 2012-07-09 10:20

代码: 全选
<?php
/*
 * zencart ONS模式分析:
 * 作者:Seaqi
 *
 * 对base类的一些感受:
 * 为zencart写第三方拓展的方式大概有:重写,config.core.php断点植入,ONS模式
 * 其实这个模式很优秀,嵌入到zencart并不生硬,但有很多人说不好听的话,看了好多插件并没有使用这个模式,悲呀
 * 通过这个模式写的任何对系统的拓展不仅方便,而且高效快捷,不影响升级!!!

 * 少了相关抽象方法 abstract function abstrupdate(){}
 * 过程化的东西太多
 * 对静态属性修改时才有引用的必要,如果只是取得数则不用引用,但是:面向对象里面都是引用!!!下面有很多&&&&&&&东东是多余的,但没心情管这些了^^
 * class notifier extends base {}好像可以不用存在,但模式需要它,它有一定的象征意义!
 *
 * */
class base {
 
  function attach(   $observer, $eventIDArray) {//去掉了&
    foreach($eventIDArray as $eventID) {//注意:绑定的事件是数组方式
      $nameHash = md5(get_class($observer).$eventID);
      //array('obs'=>&$observer, 'eventID'=>$eventID)以这种方式存到到对象事件列表
      base::setStaticObserver($nameHash, array('obs'=>  & $observer, 'eventID'=>$eventID));//去掉了&    这里引用了一个方法
    }
  }

  function detach($observer, $eventIDArray) {//解除【同上】
    foreach($eventIDArray as $eventID) {
       //md5(get_class($observer).$eventID)此方式不是为了网站安全
       //而是为了程序的开发安全,如果将键名用事件名替代,那么就会有一个连接漏洞,即绑定对象会有不稳定的现象
      $nameHash = md5(get_class($observer).$eventID);
      base::unsetStaticObserver($nameHash);
    }
  }
 
  function notify($eventID, $paramArray = array()) {//$paramArray = array()这个数组参数是留给观察者的特殊信物
    $observers = & base::getStaticObserver();//这个一定要是引用,否则操作无效
    if (!is_null($observers)) {
      foreach($observers as $key=>$obs) {
         if ($obs['eventID'] == $eventID) {//如果传过来一个未知的事件则不做什么
          $obs['obs']->update($this, $eventID, $paramArray);//$this这个引用传给观察者,可对base对象操作!!!
        }
      }
    }
  }
 
  function & getStaticProperty($var){//存储注入的对象及事件列表静态变量
    static $staticProperty;
    return $staticProperty;
  }
 
  function & getStaticObserver() {//这里一定要引用,否则不能修改静态属性
    return base::getStaticProperty('observer');
  }
 
  function   setStaticObserver($element, $value){//去掉了&
     //$element密值,$value对象事件数组
    $observer = & base::getStaticObserver();//重点:这里引用了方法getStaticObserver()但实现了:$observer->$staticProperty
    $observer[$element] = $value;//注入一个子数组【对象及事件】,将两者的密文赋予键名
  }
 
  function   unsetStaticObserver($element){//去掉了&
    $observer =  & base::getStaticObserver();
    unset($observer[$element]);
  }
}


class notifier extends base {}

//这样做是为得到一个统一的名称notifier所有的通知方式为:
//$zco_notifier->notify('');//当然也要可用任何一个继承它的子类     对象->notify('');

$zco_notifier = new notifier();




 //以下是第三方拓展:
class A extends base {
   function __construct() {
      global $zco_notifier;//这里可以用$this代替
      $zco_notifier->attach($this, array('NOTIFY_WEIBO','NOTIFY_WEIBO2'));//A观察了更多的事件
   }

   function update(   $class, $eventID,$mes) {//去掉&
      if($eventID == 'NOTIFY_WEIBO'){
         echo "我是A,我收到了女孩的信息<br />";
         if(count($mes) != 0){
            $class->detach($mes,array('NOTIFY_WEIBO'));//强制解除C与A的关系【这里建立了三个参数的关系,可以十分智能】
            echo "我已经教训了C,他已经不收听你了,保证不会干扰你<br /><br />";
         }
      }
   }
}

class B extends base {
   function __construct() {
      global $zco_notifier;
      $zco_notifier->attach($this, array('NOTIFY_WEIBO'));
   }
   function update(   $class, $eventID,$mes) {//去掉&
      if($eventID == 'NOTIFY_WEIBO'){
         echo "我是B,我收到了女孩的信息<br />";
      }
   }
}

class C extends base {
   function __construct() {
      global $zco_notifier;
      $zco_notifier->attach($this, array('NOTIFY_WEIBO'));
   }
   function update(   $class, $eventID,$mes) {//去掉&
      if($eventID == 'NOTIFY_WEIBO'){
         echo "我是C,我收到了女孩的信息<br />";
      }
   }
}


$a = new A();//在zencart断点中的适当位置进行连接,注意这里的顺序得合理
$b = new B();
$c = new C();



//以下是通知者【女孩】
echo "第一条微博:今天心情好<br />";
$zco_notifier->notify('NOTIFY_WEIBO');



echo "<br /><br /><br />";
echo "第二条微博:我【讨厌C】【A你能教训他吗】<br />";
$zco_notifier->notify('NOTIFY_WEIBO',$c);//我【讨厌C】【A你能教训他吗?他在信息我传给你】
?>

结果如下:
QQ截图20120324194126.png
QQ截图20120324194126.png (10.42 KiB) 被浏览 2586 次




/*
就上面的分析我举个例子:
有一个美丽的女孩,单身,他们公司追求他的人很多,有A,B,C
但他们之间能沟通的接口是微博,那么那四个人收听了她,则认为是她的观察者
即四个男孩同时观察一个女孩,
有一天,女孩发表微博说:我讨厌C,A你能教训他吗不让他关注我?【这里有两条事件信息】
事件信息他们都能看到,第一个事件谁敢做谁就拥有这个事件【即ABC都可以知道这件事情】,但另一条事件则只能对A生效【通常在开发中这个事件是有效的】
C是一个胆子小的坏人,本来他收到这条信息时会在下面启动对女孩不利行为事件,
但A的事件先生效,并执行了【就是A已经教训了C】让C解除了与女孩的绑定【即C对女孩不利的事件解除】
*/

//此设计模式远不止这些,我的理解可能不到位,请大家多多指教
//前几个月实在太忙了,后台多图上传做好了,但没时间整理成一个方便好安装的插件形式,所以没上传,有空分享一下,有功底的自己安装, :mrgreen:




//设计模式
/*

1.主题纯虚基类。
m_list:用于保存观察者对象的链表
Attach接口,用于增添观察者,对象
Dettach接口,删除观察者对象
Notify接口,遍历通知所有观察者对象


2.观察者纯虚基类
upadate接口,用于更新自己的行为。



*/
xiayouqiao
新手上路
新手上路
 
帖子: 17
注册: 2011-04-23 9:32
QQ 帐号: 980522557

  • 相关话题
    回复总数
    阅读次数
    最新文章

回到 精华共享



在线用户

正在浏览此版面的用户:没有注册用户 和 0 位游客