你知道什麼是 AOP 嗎?

前言

AOP 的全稱爲 Aspect Oriented Programming,意思是:面向切面編程。

爲什麼會有這篇文章?是因爲看了 Laravel 中 Pipeline 的設計,發現 Pipeline 就是基於 AOP 思想的一種實現。

說起 AOP,就不得不說起 OOP,它們又是什麼關係,有什麼區別?

AOP 與 OOP 的區別

OOP 我們都知道,全程爲 Object Oriented Programming ,意思是:面向對象編程。

首先我們要知道 AOPOOP 不是相互對立的關係,可以把 AOP 看作是彌補 OOP 的不足,以此之長、補彼之短,兩者結合使用效果最佳。

OOP 是針對業務 實體 及其 屬性行爲 進行 抽象封裝 ,這個不難理解,例如:用戶模塊、訂單模塊 等。

AOP 是針對業務切面進行提取,它所面對的是處理過程中的某個 步驟階段 ,以達到邏輯處理過程中各部分之間低耦合性的 隔離效果 ,例如:日誌記錄、權限驗證 等。

舉個例子就容易理解了,如果單純使用 OOP ,需要在日誌模塊、訂單模塊中進行權限驗證、日誌記錄怎麼辦?難道要在每個方法前都加入權限驗證、日誌記錄的代碼嗎?那麼如果需要在每個方法前和方法後都記錄日誌怎麼辦?

這時如果使用 AOP,就可以藉助代理完成這些重複的操作,就可以不在每個方法前加入權限驗證、日誌記錄的代碼,降低各部分之間的耦合。

AOP 能做什麼

除了上面說的 權限驗證、日誌記錄,AOP 還可以做 數據加解密、請求響應數據規範 ...

只要是和具體的業務無關的,同時又是業務都在關注的,那麼都可以通過 AOP 去抽離這些關注點並將其統一維護,提高代碼的複用性。

上面的業務關注點是不是有點似曾相識... 其實我們常用的 路由中間件 就是基於 AOP 思想的一種實現。

AOP 的一種實現

舉例:Laravel 中的 路由中間件

/**
 * Send the given request through the middleware / router.
 *
 * @param  \Illuminate\Http\Request  $request
 * @return \Illuminate\Http\Response
 */
protected function sendRequestThroughRouter($request)
{
    $this->app->instance('request'$request);

    Facade::clearResolvedInstance('request');

    $this->bootstrap();

    return (new Pipeline($this->app))
                ->send($request)
                ->through($this->app->shouldSkipMiddleware() ? [] : $this->middleware)
                ->then($this->dispatchToRouter());
}

通過上述代碼,可以發現需要執行的中間件配置在 through() 方法中,執行後再執行 then 方法。

上述代碼用在了 路由中間件 中,當然也可以用在其他地方,比如用到 controller 中,就可以這樣寫:

// 示例代碼

$pipes = [
    LoggingPipeline::class,   // 日誌記錄
    PermitPipeline::class,    // 權限驗證
];

return app(Pipeline::class)
    ->send($request->all())
    ->through($pipes)
    ->then(function ($content) {
        return $content;
    });

上面只是在 Laravel 中的一種實現,當然在 PHP 的其他框架中也有類似的實現,例如:YiiThinkPHP 等。

AOP 只是個思想,當然也有其他語言實現,例如:GolangJava 等。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/xp50nxByPL3K4pySCQUUOA