观察者模式,事件处理

观察者模式
过程:首先我们先创建两个类,Entity.php事件对象, Event事件方法。我们再创建一个APP.php文件用于继承Event这个类。我们在Boostrap.php中去实例化APP这个类,然后调用,往里边写内容。最后我们在controller文件里边创建一个EventController类,给Entity这个类输入数据,最后触发这个事件。

创建一个事件对象:
/**

  • 事件对象

  • Class ${解志鑫}

  • @package extend\event
    /
    class Entity
    {
    /
    *

    • @var string $name
      */
      public $name;

    /**事件触发者

    • @var object $sender
      */
      public $sender;

    /**事件是否已经被处理,如果handled为true,其他handler不会再接收到通知

    • @var bool $handled
      */
      public $handled = false;

    /**数据

    • @var mixed $data
      */
      public $data;
      }

事件通知者进行处理:
trait Event
{
/**
* @var array $_events
*/
protected $_events = [];

/**
 * Notes:绑定事件
 * User: 蜡笔
 * Date: 2019/3/18
 * Time: 15:48
 * @return void
 */
 function on($name, $handler, $append = true)
{
    $this->_events[ $name ] = isset($this->_events[ $name ]) ? $this->_events[ $name ] : [];
    $append ? array_push($this->_events[ $name ],$handler) : array_unshift($this->_events[ $name ],$handler);
}

/**
 * Notes:解绑事件
 * User: 蜡笔
 * Date: 2019/3/18
 * Time: 15:48
 * @return bool
 */
public function off($name, $handler = null)
{
    if (!isset($this->_events[ $name ])) {
        return false;
    }
    //移除所有$name事件的handler
    if ($handler === null) {
        unset($this->_events[ $name ]);
        return true;
    } else {
        $removed = false;
        foreach ($this->_events[ $name ] as $index => $eventHandler) {
            if ($eventHandler === $handler) {
                unset($this->_events[ $name ][ $index ]);
                $removed = true;
            }
        }
        if ($removed) {
            $this->_events[ $name ] = array_values($this->_events[ $name ]);
        }

        return $removed;
    }
}

/**
 * Notes:是否有handler
 * User: 蜡笔
 * Date: 2019/3/18
 * Time: 15:48
 * @return bool
 */
public function hasHandlers($name)
{
    if (isset($this->_events[ $name ]) && !empty($this->_events[ $name ])) {
        return true;
    }
    return false;
}

/**
 * Notes:触发事件
 * User: 蜡笔
 * Date: 2019/3/18
 * Time: 15:48
 * @return void
 */
public function trigger($name, $event = null)
{
    if (empty($this->_events[ $name ])) {
        return;
    }
    if ($event === null) {
        $event = new Entity();
    }
    $event->handled = false;
    $event->name = $name;
    foreach ($this->_events[ $name ] as $handler) {
        call_user_func($handler, $event);

        //标记已处理,停止后续处理
        if ($event->handled) {
            return;
        }
    }

}
下边我们实现以下观察者模式(我们利用上一节讲的DI容器来实现):
我们先创建一个app.php文件:
class App{
use Event;
}
还是在yaf框架的bootstrap.php文件中创建一个方法:

public function _initEvent(\Yaf\Dispatcher $dispatcher)
{
db=newApp();Di::set(app,db = new App(); Di::set('app',db=newApp();Di::set(′app′,app);
app>on(action:run,function(app->on('action:run',function(app−>on(′action:run′,function(entity){
Di::get(‘log’)->info(‘事件:数据’,[
‘event’=>entity>name,data=>entity->name, 'data'=>entity−>name,′data′=>entity->data
]);
});

app>on(action:run,function(app->on('action:run',function(app−>on(′action:run′,function(entity){
Di::get('log)->info(‘事件:数据’,[
‘event’=>entity>name,data=>entity->name, 'data'=>entity−>name,′data′=>entity->data-1
]);
});

}

在控制器层,我们需要用一个方法执行
创建Event.php文件:
class EventController extends Controller_Abstract{
public function indexAction()
{
$log = Di::get(‘app’);
app>on(action:run,[app->on('action:run',[app−>on(′action:run′,[this,’’]);
//移除所有事件的handler
//$app->off(‘action:run’);
app>off(action:run,[app->off('action:run',[app−>off(′action:run′,[this,‘addition’]);
$entity = new Entity();
$entity->data = time();
app>trigger(action:run,app->trigger('action:run',app−>trigger(′action:run′,entity);
}
}

上一篇:ss缩略词


下一篇:如何使用JavaScript将引导程序图标添加到画布?如果有办法