問題
初探AOP FOR PHP
解決方法
AOP是OOP的延續,是Aspect Oriented Programming的縮寫,意思是面向方面編程。AOP實際是GoF設計模式的延續,設計模式孜孜不倦追求的是調用者和被調用者之間的解耦,AOP可以說也是這種目標的一種實現。其實這個技術在很久前就出現了。我google的時候已經是06年就出現的技術。
用我的理解是,在不破壞原有方法或者類的時候將函數的進行橫向切面。然後加進自己的方法處理。比如說,我們經常有一些方法執行之前要進行權限判斷。處理之後要進行日志寫入等等操作。一般的操作方式是在方法的頭部和底部寫處理過程。這就破壞了OOP的單一功能的原則。因為當有100甚至1000個方法要許進行同樣處理的時候,難免會出現一些不必要的錯誤。這就是AOP的實際運用。。。
我們寫一個函數輸出一些信息的時候,在處理前,不希望沒有權限看到這些信息的人來看。處理之後可能會寫入一些常用緩存信息。通常的寫法是這樣 class OneTest{
public function getInfo(){
//檢查一下權限
ACL::checkRole();
//做獲取信息的動作過程;
.....
//寫入緩存
Cache::writeCache();
}
}
復制代碼如果有1000個這樣需要做同樣操作的方法怎麼辦呢。。一處修改處處修改。難維護的情況就出現了。而用AOP的辦法去處理這個問題,就只需要這樣 class OneTest{
public function getInfo(){
//做獲取信息的動作過程;
.....
}
}
復制代碼這樣兩個破壞封裝的就拿出來在其他地方統一定義了。。。。。大體就是這麼一個意思。當然理解錯誤,誤人子弟純屬巧合。
詳細介紹大家可以google。。一些資料還沒整理。。。。。這還是忙裡偷閒的時候整出來的。
下面是幾個關於php的鏈接。有興趣的可以看一下
AOP FOR PHP探討
[url=http://blog.csdn.net/xiaoxiaohai123/archive/2008/06/30/2598377.aspx]鏈接標記http://blog.csdn.net/xiaoxiaohai123/archive/2008/06/30/2598377.aspx[/url]
PHP准AOP實現
[url=http://hi.baidu.com/thinkinginlamp/blog/item/864a0ef46d93b86eddc474f3.html]鏈接標記http://hi.baidu.com/thinkinginlamp/blog/item/864a0ef46d93b86eddc474f3.html[/url]
然後自己簡單實現了一下
/**
* TSAspect{
* AOP for php
* @package
* @version $id$
* @copyright 2009-2011 SamPeng
* @author SamPeng <[[email protected]][email protected][/email]>
* @license PHP Version 5.2 {@link [url=http://www.sampeng.cn]www.sampeng.cn[/url]}
*/
class TSAspect{
/**
* instance
* 方法所屬對象引用
* @var mixed
* @access private
*/
private $instance;
/**
* method
* 方法名
* @var mixed
* @access private
*/
private $method;
/**
* aspect
* 切面保存數組
* @var array
* @access private
*/
private $aspect = array();
/**
* __construct
* 構造函數查找出所有Aspect的實現方法
* @param mixed $instance
* @param mixed $method
* @param mixed $arg
* @access public
* @return void
*/
public function __construct( $instance,$method,$arg = null ){
$this->aspect = self::findFunction();
$this->instance = $instance;
$this->method = $method;
}
public function callAspect(){
$before_arg = $this->beforeFunction();
$callBack = array( $this->instance,$this->method);
$return = call_user_func_array( $callBack,$arg );
$this->afterFunction();
}
/**
* beforeFunction
* 方法之前執行的方法集合
* @static
* @access public
* @return void
*/
protected function beforeFunction(){
$result = $this->getFunction("before");
return $result;
}
/**
* afterFunction
* 方法之後執行的方法集合
* @static
* @access public
* @return void
*/
protected function afterFunction(){
$result = $this->getFunction( "after" );
}
/**
* findFunction
* 查找所有的Aspect的方法集合.
* @static
* @access private
* @return void
*/
private static function findFunction(){
$aspect = array();
foreach ( get_declared_classes() as $class ){
$reflectionClass = new ReflectionClass( $class );
if ( $reflectionClass->implementsInterface( 'InterfaceAspect' ) )
$aspect[] = $reflectionClass;
}
return $aspect;
}
/**
* getFunction
* 調用插入的方法
* @param mixed $aspect
* @static
* @access private
* @return void
*/
private function getFunction($aspect){
$result = array();
$array = $this->aspect;
foreach ( $array as $plugin ){
if ( $plugin->hasMethod($aspect ) ){
$reflectionMethod = $plugin->getMethod( $aspect );
if ( $reflectionMethod->isStatic() ){
$items = $reflectionMethod->invoke( null );
}else{
$pluginInstance = $plugin->newInstance();
$items = $reflectionMethod->invoke( $pluginInstance );
}
//處理經過處理的集合
if ( is_array( $items ) ){
$result = array_merge( $result,$items );
}
}
}
return $result;
}
}
interface InterfaceAspect{
public static function getName();
}
class testAspect implements InterfaceAspect{
public static function getName(){
return "這是一個測試AOP";
}
public static function before(){
echo "方法執行之前";
}
public static function after(){
echo "方法執行後
";
}
}
class test{
public function samTest($arg){
echo "這是一個測試方法";
}
}
$test = new test();
$aspect = new TSAspect($test,'samTest');
$aspect->callAspect();
復制代碼輸出:
方法執行之前
這是一個測試方法
方法執行之後
網友建意:
不懂,,,對開發思想有用不?
網友建意:
思想?這其實也是一種設計模式。。。。將破壞函數單一功能的部分耦合出來。。具體實現有很多辦法。。當然PHP的是准AOP。。因為他不能像java那樣的編譯語言在編譯時的時候插入橫切面處理過程。
網友建意:
新的事物總是被人華麗的無視。。。
網友建意:
去年就知道面向切面編程了,,,用不上,,,,呵呵,,,
網友建意:
剛剛接觸面向函數式編程,Haskell 、Erlang
網友建意:
PHP實現AOP要比Java簡單的多..因為有runkit
網友建意:
自己連OOP還沒大懂呢。技術啊。追不上。