PHP之AOP思想
故事背景:
問題:
在傳統的OOP(物件導向程式設計:Object-Oriented Programming)思想裡,一般把應用程式分解成若干個的物件,強調高內聚,弱耦合,從而提高應用程式的模組化程度,但是在處理某些問題的時候,OOP會顯得不夠靈活,
比如說,應用程式裡很多業務邏輯都要在操作之初進行“許可權檢查”,在操作之後進行“日誌記錄”,如果直接把處理這些操作的程式碼加入到每個模組中,那麼無疑破壞了OOP的“單一職責”原則,模組的可重用性會大大降低,
這時候傳統的OOP設計往往採取的策略是加入相應的代理(Proxy)層來完成系統的功能要求,但這樣的處理明顯使系統整體增加了一個層次的劃分,複雜性也隨之增加,從而給人過於厚重的感覺。
解決方案:
正是為了處理這樣的問題,AOP(面向方面程式設計:Aspect-Oriented Programming)思想應運而生了,假設把應用程式想成一個立體結構的話,OOP的利刃是縱向切入系統,把系統劃分為很多個模組(如:使用者模組,文章模組等等),而AOP的利刃是橫向切入系統,提取各個模組可能都要重複操作的部分(如:許可權檢查,日誌記錄等等)。由此可見,AOP是OOP的一個有效補充。
就目前的PHP來說,還沒有一個完整的AOP內建實現,雖然出現了RunKit,但一直都以BE他的狀態呆在PECL專案裡,估計很長時間內不太可能成為PHP的預設設定。那是不是AOP在PHP裡就破滅了呢?當然不是,因為我們有__get(),__set(),__call()等魔術方法,合理使用這些方法可以為我們實現某種程度的“準AOP”能力,之所以說是準AOP,是因為單單從實現上來看,稱其為AOP有些牽強,但是從效果上來看,又部分實現了AOP的作用,雖然其實現方式並不完美,但對於一般的使用已經足夠了。
<?php
class BIZ
{
public function foobar($num)
{
print_r($num);
echo "\n業務邏輯 do something";
}
}
class AOP{
private $instance;
public function __construct($instance){
$this->instance = $instance;
}
public function __call($method,$argument) {
if (!method_exists($this->instance, $method)) {
throw new Exception('未定義的方法:' . $method);
}
echo "\n許可權檢查"; //--------------AOP
$callBack = array($this->instance,$method);
$return = call_user_func($callBack,$argument);
echo "\n日誌記錄"; //--------------AOP
return $return;
}
}
class Factory
{
public static function getBizInstance()
{
return new AOP(new BIZ());
}
}
try {
$obj = Factory::getBizInstance();
$obj->foobar(3);
} catch (Exception $e) {
echo 'Exception '.$e->getMessage();
}
/** * 總結: * 整個的實現思路其實很簡單,關鍵就是客戶端請求的物件不能直接例項化出來, * 而是利用工廠方法返回一個請求物件的包裝物件,在包裝物件內利用魔術方法來處理許可權處理,日誌記錄等公共操作。 * 這既是巧妙的地方,也是最有可能出問題的地方,因為客戶端使用物件並不是它想象中的物件, * 而是一個包裝後的物件,比如說,客戶端通過getBizInstance()方法以為得到的物件是BIZ, * 但實際上它得到的是一個BIZ的包裝物件AOP,這樣的話,如果客戶端進行一些諸如get_class()之類 * 和物件型別相關的操作就會出錯,當然,大多數情況下,客戶端似乎不太會做類似的操作 */
相關文章
- Spring框架系列之AOP思想Spring框架
- Spring核心思想之 AOP:在自定義容器基礎上實現AOP功能Spring
- ThinkPHP 類似 AOP 思想的引數驗證PHP
- [Spring之AOP]Spring
- Spring 3.0 AOP 之 AOP 術語 (一)Spring
- Unity應用架構設計(12)——AOP思想的實踐Unity應用架構
- (三)Spring的AOP思想2018-06-29Spring
- Aop 設計 - 使用 PHP-parser 重寫 PHP 類PHP
- pinpoint-php-aop 內部原理PHP
- .Net Core Aop之IResourceFilterFilter
- AOP之動態代理
- Go 之反射基本思想Go反射
- 架構思想之CAP原理架構
- 全新MacBook之設計思想Mac
- 死磕Spring之AOP篇 - Spring AOP總覽Spring
- Spring之AOP實現Spring
- Spring之Aop練習Spring
- (002)Spring 之 AOPSpring
- 常用演算法思想之動態規劃的字尾思想演算法動態規劃
- Spring Boot之IOC&AOPSpring Boot
- AOP底層原理之CGlibCGLib
- Spring AOP之原始碼分析Spring原始碼
- 死磕Spring之AOP篇 - Spring AOP常見面試題Spring面試題
- Spring核心思想之 AOP:如何影響DI並引入三級快取解決DI中涉及代理的問題Spring快取
- PHP 實際開發需求中使用到 AOP AspectPHP
- Spring系列之aAOP AOP是什麼?+xml方式實現aop+註解方式實現aopSpringXML
- 死磕Spring之AOP篇 - Spring AOP自動代理(一)入口Spring
- 老生常談之Flux與Redux思想Redux
- java程式設計思想之註解Java程式設計
- SOA標準之—-JBI架構思想架構
- SpringBoot學習之整合AOPSpring Boot
- Spring核心系列之AOP(一)Spring
- Spring核心系列之AOP(二)Spring
- PHP中的服務容器與依賴注入的思想PHP依賴注入
- js陣列去重之核心思想JS陣列
- 系統設計思想之Domain驅動AI
- 死磕Spring之AOP篇 - Spring AOP註解驅動與XML配置SpringXML
- 死磕Spring之AOP篇 - Spring AOP自動代理(三)建立代理物件Spring物件