原文: https://blog.csdn.net/yhl27/article/details/8705313
--------------------------------------------------------------------------
php中实现事件驱动
}
}
以上代码中主要编入了验证逻辑,判断用户是否登录,并且是某个角色,然后符合要求后再执行正常的执行逻辑,如果这样的逻辑确实是每个事件响应器必须执行的那么可以提取到抽象类中,并重新设计一个方法叫:secureHandle()
使之为抽象的强迫子类实现,并改写分发器:改为调用这个secureHandle()方法,这时接口可能也要改,在php中接口可能只是一个约定而已,如果不进行类型检查那么接口看似可有可无。这样的方案个人感觉不是太好,所以给出一个我认为还可以接受的方案:
改写抽象类:
abstract class EventHandler
{
private $pdo;
function getPdo(){
$this->pdo = new PDO('配置串');
return $pdo;
}
//使用模板方法设计模式
public function handle($eventContext){
try{
//如果有参数就传进来
$this->_before($eventContext);
$response = $this->_handle($eventContext);
$this->_after($eventContext);
return $response;
}catch(Exception $ex){
//是重抛还是如何处理取决于你的异常处理策略
}
}
protected funciton _before(&$_context){
//这里做验证 不通过 就抛一个验证失败的异常。
}
protected function _after(&$_context){
//这里随便做啥 或者日志吧!
}
//强迫子类实现这个方法
abstract function _handle(&$_context);
}
经过以上改写,应用了模板方法设计模式 可以把验证提到_before操作中,把_handle方法设计为抽象的强迫子类实现
如果子类还想更改安全验证策略只需要覆写_before操作即可。这样原先的接口,事件分发器,都不需要改动。另外这里也用到了before/after设计模式。请自己查找相关资料。现在子类唯一要做的是复写_handle方法,必要时复写_before方法。
*****
**************
结语:
还有许多问题值得考虑,这里只给出了大概的思路,比如GUI领域中常常出现的事件注册机制是否需要,主要用来根据事件查找对应的处理器,当然这个映射完全可以来自配置文件,或者数据库。如果结合上访问控制列表技术,每一个用户都有一个对应的可操作的事件处理器集,可以根据当前用户Id加载其所有可用的事件处理器列表,然后再调用相应处理器的方法,如果列表中找不到对应于事件的处理器证明当前用户没有这个权利。这个逻辑就可以提取到抽象类中来实现。
另一个值得考虑的问题是类加载问题,一个方法是把系统可能用到的类文件提前全部include进来,这在小项目中是可行的,但是对于第三方库或者有多个文件夹且相互嵌套时 这种方法会很笨拙。另一种方法是在事件分发器加载类之前从一个配置文件中读取相关类和类所在文件的映射信息,然后把类文件包含进来。还有一个就是zendFramework用的把文件夹加进类路径中include_path然后使用自动加载spl_autoload技术。我前面有一个自己写的自动加载类可以用的!
}
以上代码中主要编入了验证逻辑,判断用户是否登录,并且是某个角色,然后符合要求后再执行正常的执行逻辑,如果这样的逻辑确实是每个事件响应器必须执行的那么可以提取到抽象类中,并重新设计一个方法叫:secureHandle()
使之为抽象的强迫子类实现,并改写分发器:改为调用这个secureHandle()方法,这时接口可能也要改,在php中接口可能只是一个约定而已,如果不进行类型检查那么接口看似可有可无。这样的方案个人感觉不是太好,所以给出一个我认为还可以接受的方案:
改写抽象类:
abstract class EventHandler
{
private $pdo;
function getPdo(){
$this->pdo = new PDO('配置串');
return $pdo;
}
//使用模板方法设计模式
public function handle($eventContext){
try{
//如果有参数就传进来
$this->_before($eventContext);
$response = $this->_handle($eventContext);
$this->_after($eventContext);
return $response;
}catch(Exception $ex){
//是重抛还是如何处理取决于你的异常处理策略
}
}
protected funciton _before(&$_context){
//这里做验证 不通过 就抛一个验证失败的异常。
}
protected function _after(&$_context){
//这里随便做啥 或者日志吧!
}
//强迫子类实现这个方法
abstract function _handle(&$_context);
}
经过以上改写,应用了模板方法设计模式 可以把验证提到_before操作中,把_handle方法设计为抽象的强迫子类实现
如果子类还想更改安全验证策略只需要覆写_before操作即可。这样原先的接口,事件分发器,都不需要改动。另外这里也用到了before/after设计模式。请自己查找相关资料。现在子类唯一要做的是复写_handle方法,必要时复写_before方法。
*****
**************
结语:
还有许多问题值得考虑,这里只给出了大概的思路,比如GUI领域中常常出现的事件注册机制是否需要,主要用来根据事件查找对应的处理器,当然这个映射完全可以来自配置文件,或者数据库。如果结合上访问控制列表技术,每一个用户都有一个对应的可操作的事件处理器集,可以根据当前用户Id加载其所有可用的事件处理器列表,然后再调用相应处理器的方法,如果列表中找不到对应于事件的处理器证明当前用户没有这个权利。这个逻辑就可以提取到抽象类中来实现。
另一个值得考虑的问题是类加载问题,一个方法是把系统可能用到的类文件提前全部include进来,这在小项目中是可行的,但是对于第三方库或者有多个文件夹且相互嵌套时 这种方法会很笨拙。另一种方法是在事件分发器加载类之前从一个配置文件中读取相关类和类所在文件的映射信息,然后把类文件包含进来。还有一个就是zendFramework用的把文件夹加进类路径中include_path然后使用自动加载spl_autoload技术。我前面有一个自己写的自动加载类可以用的!