zoukankan      html  css  js  c++  java
  • PHP一个类AOP的实现

    由于项目有一个需求,需要在原来的代码上做一个封装. 由于不想修改原有代码, 查了一下, PHP没有方便的支持AOP的方法,于是参考了网上一些文章,写了个包装器, 可以在不修改原有代码的基础上为函数添加before和after实现.

     
    标签: <无>
     

    代码片段(3)[全屏查看所有代码]

    1. [代码]核心类     

    01 <?php
    02  
    03 /**
    04  * 包装器(Wrapper).
    05  * Wrapper是一个AOP_LIKE的实现. 也可以看作监听者模式的实现.
    06  * 一个Wrapper报装了一个对象(source). source可以是任意对象(不包括数组及原子类型),甚至是一个Wrapper.
    07  *
    08  * 包装器可以任意添加饰品(Decoration).通过Wrapper调用source的函数的流程将是:
    09  *  unpacking --> teardown --> open --> setup --> packing.
    10  *
    11  *  例如调用source->doXX(),各个流程将是:
    12  *  unpacking:  解包. 这是调用任意source的函数都会调用的方法;
    13  *  teardown:   撕掉饰品. 对于Wrapper中的每个Decoration,调用其before()函数;
    14  *  open:       真正调用source->doXX()函数;
    15  *  setup:      重新贴上饰品. 对于Wrapper中的每个Decoration,调用其after()函数;
    16  *  packing:    重新打包.  这是调用任意source的函数都会调用的方法;
    17  *
    18  */
    19 class Wrapper{
    20     private $source;
    21  
    22     /**
    23      * @var bool
    24      */
    25     private $undecorated;
    26  
    27     /**
    28      * @var array[Decoration]
    29      */
    30     private $decorations=array();
    31  
    32     public function __construct($source){
    33         $this->source = $source;
    34     }
    35  
    36     public function __call($name,$parameters){
    37         $this->unpacking($name,$parameters);
    38         $this->tearDown($name,$parameters);
    39  
    40         // opening
    41         if(method_exists($this->source, $name)){
    42             $retval = call_user_func_array(array($this->source,$name),$parameters);
    43         }
    44  
    45         $this->setup($retval,$name,$parameters);
    46         $this->packing($retval,$name,$parameters);
    47  
    48         return $retval;
    49     }
    50  
    51     public function unpacking($name,$parameters){
    52     }
    53  
    54     public function packing($name,$parameters){
    55     }
    56  
    57     public function tearDown($name,$parameters){
    58         if($this->undecorated){
    59             return;
    60         }
    61         foreach ($this->decorations as $d){
    62             $d->before($name,$parameters);
    63         }
    64     }
    65  
    66     public function setup($retval,$name,$parameters){
    67         if($this->undecorated){
    68             return ;
    69         }
    70         foreach ($this->decorations as $d){
    71             $d->after($retval,$name,$parameters);
    72         }
    73     }
    74  
    75     public function decarate($decoration){
    76         $this->decorations[] = $decoration;
    77     }
    78  
    79  
    80  
    81     public static function wrap($source){
    82         //  wrap the source
    83         $wrapperConfig = app()->wrappers[get_class($source)];
    84         if($wrapperConfig){
    85             $wrapperClass $wrapperConfig['class'];
    86             $wrapper new $wrapperClass($source);
    87  
    88             foreach ($wrapperConfig['decorations'as $item){
    89                 $decoration new $item;
    90                 $wrapper->decarate($decoration);
    91             }
    92         }
    93         return $wrapper?$wrapper:$source;
    94     }
    95  
    96 }
    97  
    98 ?>

    2. [代码]配置     

    01 'wrappers'=>array(
    02         'ContentService'=>array(
    03                 'class'=>'ContentWrapper',
    04                 'decorations'=>array(
    05                         'DasaiContentDecoration',
    06                 )
    07         ),
    08         'AOPWorker'=>array(//for test
    09             'class'=>'DiagnosisWrapper',
    10             'decorations'=>array(
    11                 'DasaiDiagnosisDecoration'
    12             ),
    13         ),
    14 ),

    3. [代码]测试代码     

    01 class AOPWorker{
    02     public function testAOP(){
    03         Debugger::print_r(
    04             " 工人:我要做一大堆操作了
    05                  工人:... ...
    06                  工人:好了 做完了 ");
    07         return 'OK';
    08     }
    09  
    10 }
    11  
    12  
    13 public function testAOP(){// test aop  测试入口
    14         $aop = Wrapper::wrap(new AOPWorker());
    15         $aop->testAOP(33347);
    16 }
    17  
    18  
    19  
    20 class DiagnosisWrapper extends Wrapper{
    21  
    22     public function unpacking($name$parameters){
    23         echo " DiagnosisWrapper:喂,有人调用$name,我要解包了. ";
    24     }
    25  
    26  
    27     public function packing($retval,$name$parameters){
    28         echo " DiagnosisWrapper:喂,调用$name,结果为$retval,重新打包好了. ";
    29     }
    30 }
    31  
    32  
    33  
    34 class DasaiDiagnosisDecoration extends Decoration {
    35     public function before($name,$parameters){
    36         echo " DasaiDiagnosisDecoration:开始调用$name,已经告诉张三李四了. ";
    37     }
    38  
    39     public function after($retval,$name,$parameters){
    40         echo " DasaiDiagnosisDecoration:结束调用$name,告诉霍金和Sheldon了. ";
    41     }

    42 }
  • 相关阅读:
    HTCVive摄像头的一些好玩的现象
    AI之A*算法
    C#预处理器指令之#define/#undefine/#if/#elif/#else/#endif
    AI之有限状态机
    Unity之动态加载场景资源
    Canvas
    DFGUI之界面文字显示异常
    Unity Application
    AI:确定性AI
    php正则表达式
  • 原文地址:https://www.cnblogs.com/shsgl/p/3934326.html
Copyright © 2011-2022 走看看