PHP一个类AOP的实现

1.Wrapper.class.php

<?php

/**
 * 包装器(Wrapper).
 * Wrapper是一个AOP_LIKE的实现. 也可以看作监听者模式的实现.
 * 一个Wrapper报装了一个对象(source). source可以是任意对象(不包括数组及原子类型),甚至是一个Wrapper.
 *
 * 包装器可以任意添加饰品(Decoration).通过Wrapper调用source的函数的流程将是:
 *	unpacking --> teardown --> open --> setup --> packing.
 *
 *	例如调用source->doXX(),各个流程将是:
 *	unpacking: 	解包. 这是调用任意source的函数都会调用的方法;
 *	teardown: 	撕掉饰品. 对于Wrapper中的每个Decoration,调用其before()函数;
 *	open: 		真正调用source->doXX()函数;
 *	setup: 		重新贴上饰品. 对于Wrapper中的每个Decoration,调用其after()函数;
 *	packing:	重新打包.  这是调用任意source的函数都会调用的方法;
 *
 */
class Wrapper{
	private $source;

	/**
	 * @var bool
	 */
	private $undecorated;

	/**
	 * @var array[Decoration]
	 */
	private $decorations=array();

	public function __construct($source){
		$this->source = $source;
	}

	public function __call($name,$parameters){
		$this->unpacking($name,$parameters);
		$this->tearDown($name,$parameters);

		//opening
		$retval = $this->opening($name,$parameters);

		$this->setup($retval,$name,$parameters);
		$this->packing($retval,$name,$parameters);

		return $retval;
	}

	public function unpacking($name,$parameters){
	}

	public function packing($name,$parameters){
	}
	
	private function opening($name,$parameters){
		// opening
		if(method_exists($this->source, $name)){
			$retval = call_user_func_array(array($this->source,$name),$parameters);
		}
		
		return $retval;
	}

	public function tearDown($name,$parameters){
		if($this->undecorated){
			return;
		}
		$before='before';
		foreach ($this->decorations as $d){
			if(method_exists($d, $before))
			{ 
				$d->$before($name,$parameters);
			} 
		}
	}

	public function setup($retval,$name,$parameters){
		if($this->undecorated){
			return ;
		}
		$after='after';
		foreach ($this->decorations as $d){
			if(method_exists($d, $after))
			{ 
				$d->$after($retval,$name,$parameters);
			} 
		}
	}

	public function decarate($decoration){
		$this->decorations[] = $decoration;
	}



	public static function wrap($source){
		//  wrap the source
		$wrapperConfig = Aop::app()->wrappers[get_class($source)];
		if($wrapperConfig){
			$wrapperClass = $wrapperConfig['class'];
			$wrapper = new $wrapperClass($source);

			foreach ($wrapperConfig['decorations'] as $item){
				if(class_exists($item)){
					$decoration = new $item;
					$wrapper->decarate($decoration);
				}
			}
		}
		return $wrapper?$wrapper:$source;
	}

}

?>

2. test.php 

 
  

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />


<?php


require 'Wrapper.class.php';


//该类和Wrapper类联合使用,用来获取配置文件
class Aop{
//var wrappers=array();

function __construct(){
   //配置文件
$this->wrappers=array(
'ContentService'=>array(
'class'=>'ContentWrapper',
'decorations'=>array(
'DasaiContentDecoration',
)
),
'AOPWorker'=>array(//for test
'class'=>'DiagnosisWrapper',
'decorations'=>array(
'DasaiDiagnosisDecoration'
),
),
);

}

public static function app(){
return new Aop();

}
}






class AOPWorker{
public function testAOP(){
echo '<br>这里是调用的地方 <br>';
return 'OK';
}


}




class DiagnosisWrapper extends Wrapper{


public function unpacking($name, $parameters){
echo "DiagnosisWrapper:喂,有人调用$name,我要解包了.<br>";
}




public function packing($retval,$name, $parameters){
echo "DiagnosisWrapper:喂,调用$name,结果为$retval,重新打包好了.<br>";
}
}






class DasaiDiagnosisDecoration  {
public function before($name,$parameters){
echo "DasaiDiagnosisDecoration:开始调用$name , 信息 :$parameters[0] 已经告诉张三李四了.<br>";
}


public function after($retval,$name,$parameters){
echo "<br>DasaiDiagnosisDecoration:结束调用$name,告诉霍金和Sheldon了.<br>";
}
}




function testAOP(){// test aop  测试入口
$aop = Wrapper::wrap(new AOPWorker());
$aop->testAOP(33347);
}




testAOP();












?>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值