PHP 面向切面編程


 面向切面編程介紹:


介紹:

AOP(Aspect-Oriented Programming,面向方面編程),可以說是OOP(Object-Oriented Programing,面向對象編程)的補充和完善。OOP引入封裝、繼承和多態性等概念來建立一種對象層次結構,用以模擬公共行為的一個集合。 當我們需要為分散的對象引入公共行為的時候,OOP則顯得無能為力。也就是說, OOP允許你定義從上到下的關系,但並不適合定義從左到右的關系。例如日志功能。日志代碼往往水平地散布在所有對象層次中,而與它所散布到的對象的核心功能毫無關系。對於其他類型的代碼,如安全性、異常處理和透明的持續性也是如此。這種散布在各處的無關的代碼被稱為橫切(cross-cutting)代碼,在OOP設計中,它導致了大量代碼的重復,而不利於各個模塊的重用。
 
而AOP技術則恰恰相反,它利用一種稱為“橫切”的技術,剖解開封裝的對象內部,並將那些影響了多個類的公共行為封裝到一個可重用模塊,並將其名為“Aspect”,即方面。所謂“方面”,簡單地說, 就是將那些與業務無關,卻為業務模塊所共同調用的邏輯或責任封裝起來,便於減少系統的重復代碼,降低模塊間的耦合度,並有利於未來的可操作性和可維護性。AOP代表的是一個橫向的關系,如果說“對象”是一個空心的圓柱體,其中封裝的是對象的屬性和行為;那么面向方面編程的方法,就仿佛一把利刃,將這些空心圓柱體剖開,以獲得其內部的消息。而剖開的切面,也就是所謂的“方面”了。然后它又以巧奪天功的妙手將這些剖開的切面復原,不留痕跡。
 

使用“橫切”技術,AOP把軟件系統分為兩個部分:核心關注點和橫切關注點。業務處理的主要流程是核心關注點,與之關系不大的部分是橫切關注點。橫切關注點的一個特點是,他們經常發生在核心關注點的多處,而各處都基本相似。比如權限認證、日志、事務處理。Aop 的作用在於分離系統中的各種關注點,將核心關注點和橫切關注點分離開來。正如Avanade公司的高級方案構架師Adam Magee所說,AOP的核心思想就是“將應用程序中的商業邏輯同對其提供支持的通用服務進行分離。”
實現AOP的技術,主要分為兩大類:
一是采用動態代理技術,利用截取消息的方式,對該消息進行裝飾,以取代原有對象行為的執行;二是采用靜態織入的方式,引入特定的語法創建“方面”,從而使得編譯器可以在編譯期間織入有關“方面”的代碼。*然而殊途同歸,實現AOP的技術特性卻是相同的,分別為:

  • join point(連接點):是程序執行中的一個精確執行點,例如類中的一個方法。它是一個抽象的概念,在實現AOP時,並不需要去定義一個join point。
  • point cut(切入點):本質上是一個捕獲連接點的結構。在AOP中,可以定義一個point cut,來捕獲相關方法的調用。
  • advice(通知):是point cut的執行代碼,是執行“方面”的具體邏輯。
  • aspect(方面):point cut和advice結合起來就是aspect,它類似於OOP中定義的一個類,但它代表的更多是對象間橫向的關系。
  • introduce(引入):為對象引入附加的方法或屬性,從而達到修改對象結構的目的。有的AOP工具又將其稱為mixin。

上述的技術特性組成了基本的AOP技術,大多數AOP工具均實現了這些技術。它們也可以是研究AOP技術的基本術語。

要點:
把模塊作為一批關注點來實現

關注點識別:三棱鏡法則

將橫切關注點織入到核心關注點中

 

為了建立松散耦合的、可擴展的企業系統,AOP應用到的橫切技術,通常分為兩種類型:動態橫切和靜態橫切。

動態橫切是通過切入點和連接點在一個方面中創建行為的過程,連接點可以在執行時橫向地應用於現有對象。動態橫切通常用於幫助向對象層次中的各種方法添加日志記錄或身份認證。在很多應用場景中,動態橫切技術基本上代表了AOP。

AOP動態橫切的技術實現

 

靜態橫切和動態橫切的區別在於它不修改一個給定對象的執行行為。相反,它允許通過引入附加的方法字段和屬性來修改對象的結構。此外,靜態橫切可以把擴展和實現附加到對象的基本結構中。在AOP實現中,通常將靜態橫切稱為introduce或者mixin。

靜態橫切在AOP技術中,受到的關注相對較少。事實上,這一技術蘊含的潛力是巨大的。使用靜態橫切,架構師和設計者能用一種真正面向對象的方法有效地建立復雜系統的模型。靜態橫切允許您不用創建很深的層次結構,以一種本質上更優雅、更逼真於現實結構的方式,插入跨越整個系統的公共行為。尤其是當開發應用系統時,如果需要在不修改原有代碼的前提下,引入第三方產品和API庫,則靜態橫切技術將發揮巨大的作用。


實現:橫切

  java:實現:www.jianshu.com/p/a833d114099a

  php 簡單實例:

<?php

//Object Data
class User
{
  private $name;
  //Join Point 連接點
  function set_name( $value )
  {
    $this->name = $value;
  }
  //Join Point 連接點
  function get_name()
  {
	echo "COde......\n";
    return $this->name;
  }
}

//Aspect 方面
class Logged
{
  private $obj;
  //Point Cut 切入點
  function __call( $method, $args )
  {
	  //Advice 通知
	  echo( "$method( ".join( ",", $args )." )\n" );
	  $cron =  call_user_func_array(array(&$this->obj,$method),$args);
	  echo( "$method( ".join( ",", $args )." )END--\n" );
	  return $cron;
  }
 
  function __construct( $obj )
  {
    $this->obj = $obj;
  }
}

$c1 = new Logged( new User() );
$c1->set_name( "XuGuo" );
$name = $c1->get_name();
echo( "name = $name\n" );

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM