PHP一个类AOP的实现
代码片段(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 | classWrapper{ | 
| 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 |     publicfunction__construct($source){ | 
| 33 |         $this->source = $source; | 
| 34 |     } | 
| 35 | 
| 36 |     publicfunction__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 |     publicfunctionunpacking($name,$parameters){ | 
| 52 |     } | 
| 53 | 
| 54 |     publicfunctionpacking($name,$parameters){ | 
| 55 |     } | 
| 56 | 
| 57 |     publicfunctiontearDown($name,$parameters){ | 
| 58 |         if($this->undecorated){ | 
| 59 |             return; | 
| 60 |         } | 
| 61 |         foreach($this->decorations as$d){ | 
| 62 |             $d->before($name,$parameters); | 
| 63 |         } | 
| 64 |     } | 
| 65 | 
| 66 |     publicfunctionsetup($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 |     publicfunctiondecarate($decoration){ | 
| 76 |         $this->decorations[] = $decoration; | 
| 77 |     } | 
| 78 | 
| 79 | 
| 80 | 
| 81 |     publicstaticfunctionwrap($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 | classAOPWorker{ | 
| 02 |     publicfunctiontestAOP(){ | 
| 03 |         Debugger::print_r( | 
| 04 |             "\n工人:我要做一大堆操作了 | 
| 05 |                 \n工人:... ... | 
| 06 |                 \n工人:好了 做完了\n"); | 
| 07 |         return'OK'; | 
| 08 |     } | 
| 09 | 
| 10 | } | 
| 11 | 
| 12 | 
| 13 | publicfunctiontestAOP(){// test aop  测试入口 | 
| 14 |         $aop= Wrapper::wrap(newAOPWorker()); | 
| 15 |         $aop->testAOP(33347); | 
| 16 | } | 
| 17 | 
| 18 | 
| 19 | 
| 20 | classDiagnosisWrapper extendsWrapper{ | 
| 21 | 
| 22 |     publicfunctionunpacking($name, $parameters){ | 
| 23 |         echo"\nDiagnosisWrapper:喂,有人调用$name,我要解包了.\n"; | 
| 24 |     } | 
| 25 | 
| 26 | 
| 27 |     publicfunctionpacking($retval,$name, $parameters){ | 
| 28 |         echo"\nDiagnosisWrapper:喂,调用$name,结果为$retval,重新打包好了.\n"; | 
| 29 |     } | 
| 30 | } | 
| 31 | 
| 32 | 
| 33 | 
| 34 | classDasaiDiagnosisDecoration extendsDecoration { | 
| 35 |     publicfunctionbefore($name,$parameters){ | 
| 36 |         echo"\r\nDasaiDiagnosisDecoration:开始调用$name,已经告诉张三李四了.\n"; | 
| 37 |     } | 
| 38 | 
| 39 |     publicfunctionafter($retval,$name,$parameters){ | 
| 40 |         echo"\nDasaiDiagnosisDecoration:结束调用$name,告诉霍金和Sheldon了.\n"; | 
| 41 |     } | 
| 42 | } | 
 
                    
                 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号