Deprecated: The each() function is deprecated. This message will be suppressed on further calls in /home/zhenxiangba/zhenxiangba.com/public_html/phproxy-improved-master/index.php on line 456
pecl-AOPの紹介 | PPTX
[go: Go Back, main page]

@Hiraku
自己紹介
 @Hiraku(中野 拓)
 Webプログラマやってます
 PHP歴4年


 http://blog.tojiru.net/
 https://github.com/hirak
Wikipedia先生の解説

 アスペクト指向プログラミング
 Aspect Oriented Programming


   オブジェクト指向ではうまく分離できな
    い特徴(クラス間を横断 (cross-
    cutting) するような機能)を「アスペ
    クト」とみなし、アスペクト記述言語を
    もちいて分離して記述することでプログ
    ラムに柔軟性をもたせようとする試み。
具体例
 例外処理
 関数キャッシュ
 ロギング
 トランザクション
 実行時間の計測


   etc..
try {
  doSomething();
  //…

} catch (OutOfBoundsException $e) {
  recoverError($e);

} catch (RangeException $e) {
  recoverError($e);

}

    例外処理
class A {

                                      よくある光景
  function a() {
    try {
      doSomething();
      //…
    } catch (RuntimeException $e) {
      processError($e);
    }
  }
  function b() {
    try {
      doSomething();
      //…
    } catch (RuntimeException $e) {
      processError($e);
    }
  }
  function c() {
    try {
      doSomething();
      //…
    } catch (RuntimeException $e) {
      processError($e);
    }
  }
}
例外処理の問題
   いくらエラーの回復処理を関数化しても、
    try ~ catchブロック自体は何度も書く
    ことに

 DRY(Don't Repeat Yourself)じゃない
 「これ、さっきも書いたコードだな…」
   クラス分割や関数分割だけだとうまくモ
    ジュール化できないもの




     横断的関心事=Aspect
こういうパターンが多い
                  function a() {
                    try {
                      doSomething();
                      //…
                    } catch (RuntimeException $e) {
                      processError($e);
                    }
                  }

                                            こう分割できたらいいのに…


try {                                       function a() {
  //…                                         doSomething();
} catch (RuntimeException $e) {               //…
  processError($e);                         }
}
pecl-AOP
 AOPをextensionによって実装したもの
 http://pecl.php.net/package/AOP


 インストールさえできれば文法はわかり
  やすい
 runkitっぽい


# pecl install aop-beta
AOP用語(pecl-AOPの場合)
   Advice
     Aspectをモジュール化したもの。pecl-AOP
     ではコールバック関数で実装
   Joinpoint
     Adviceを織り込める場所。
   weave
     AdviceをJoinpointに差し込むこと。
例外処理をAdvice化
function processError(AopJoinpoint $joinpoint) {
  try {
    return $joinpoint->process();

    } catch (RuntimeException $e) {
      //エラー処理

    }
}
Weave(織り込む)
aop_add_around('A->*()', 'processError');

   AクラスのすべてのメソッドにprocessError()を織り込む、という指令
   これでAクラスのすべてのメソッドは、processError経由で呼ばれるよ
    うになる
class A {
  function a() {
    try {
      doSomething();
      //…
    } catch (RuntimeException $e) {
      processError($e);
    }
  }
  function b() {
    try {
      doSomething();
      //…
    } catch (RuntimeException $e) {
      processError($e);
    }
  }
  function c() {
    try {
      doSomething();
      //…
    } catch (RuntimeException $e) {
      processError($e);
    }
  }
}
class A {

                                         DRYになったね!
  function a() {
    doSomething();
    //…
  }
  function b() {
    doSomething();
    //…
  }
  function c() {
    doSomething();
    //…
  }
}

aop_add_around('A->*()', function (AopJoinpoint $joinpoint) {
  try {
    return $joinpoint->process();
  } catch (RuntimeException $e) {
    //エラー処理
  }
});
対応Joinpoint
 before any method / function call
 after any method / function call
 around any method / function call
 During the arousing of an exception
  of any method / function
 after any method / function call,
  should the method terminate
  normally or not (triggers an
  exception or not)
応用例はいっぱいありそう
 例外処理
 関数キャッシュ
 入出力のフィルタリング
 ロギング
 トランザクション
 実行時間の計測


   etc..
関数キャッシュ
   関数自体にキャッシュシステムを組み込む
add_aop_around('A->*()', function (AopJoinpoint $joinpoint) {
  $key = $joinpoint->getClassName() . '->' . $joinpoint->getMethodName();
  $cache = apc_fetch($key, $success);

 if ($success) {
   return $cache;
 }

 $result = $joinpoint->process();
 apc_store($key, $result);

  return $result;
});
pecl-AOPのヤバいところ
   既存の関数やメソッドなら何でも置き換
    え可能

   テストのモックとして強力
rand()の固定化
aop_add_around('rand()', function () {
  return 0;
});

var_dump(rand());
var_dump(rand());
var_dump(rand());




 rand()を同じ値しか返さない関数で置換
 何度実行しても0を返す
time()の固定化
aop_add_around('time()', function () {
  return 0;
});

var_dump(time());




   time()も初期値を自由に変更できる

   201X年を再現する、ということが可能
     timecopの方が特化してて便利だけど…
      それに近いことが可能
     https://github.com/hnw/php-timecop
何でも置き換え
 WebAPIにリクエストする部分を固定化
  とか
 DBに接続する部分を固定化とか


 要はクラスの継承と無関係な継承・上書
  きが可能
 自由すぎてわけわからん


   超強力 & 凶悪
pecl-AOP面白いよ
   超強力 & 凶悪

 テストのお供に
 書きにくいコードをすっきりDRYに


   PHPのゆるさが5割増しになるのが悩ま
    しい
注意点
 まだbeta扱いです。
 インストールもこけたりテストもこけた
  りする
 segmentation faultもよく起きる


   実戦投入はまだ危険

pecl-AOPの紹介

  • 1.
  • 2.
    自己紹介  @Hiraku(中野 拓) Webプログラマやってます  PHP歴4年  http://blog.tojiru.net/  https://github.com/hirak
  • 4.
    Wikipedia先生の解説  アスペクト指向プログラミング  AspectOriented Programming  オブジェクト指向ではうまく分離できな い特徴(クラス間を横断 (cross- cutting) するような機能)を「アスペ クト」とみなし、アスペクト記述言語を もちいて分離して記述することでプログ ラムに柔軟性をもたせようとする試み。
  • 5.
    具体例  例外処理  関数キャッシュ ロギング  トランザクション  実行時間の計測  etc..
  • 6.
    try { doSomething(); //… } catch (OutOfBoundsException $e) { recoverError($e); } catch (RangeException $e) { recoverError($e); } 例外処理
  • 7.
    class A { よくある光景 function a() { try { doSomething(); //… } catch (RuntimeException $e) { processError($e); } } function b() { try { doSomething(); //… } catch (RuntimeException $e) { processError($e); } } function c() { try { doSomething(); //… } catch (RuntimeException $e) { processError($e); } } }
  • 8.
    例外処理の問題  いくらエラーの回復処理を関数化しても、 try ~ catchブロック自体は何度も書く ことに  DRY(Don't Repeat Yourself)じゃない  「これ、さっきも書いたコードだな…」
  • 9.
    クラス分割や関数分割だけだとうまくモ ジュール化できないもの 横断的関心事=Aspect
  • 10.
    こういうパターンが多い function a() { try { doSomething(); //… } catch (RuntimeException $e) { processError($e); } } こう分割できたらいいのに… try { function a() { //… doSomething(); } catch (RuntimeException $e) { //… processError($e); } }
  • 12.
    pecl-AOP  AOPをextensionによって実装したもの  http://pecl.php.net/package/AOP インストールさえできれば文法はわかり やすい  runkitっぽい # pecl install aop-beta
  • 13.
    AOP用語(pecl-AOPの場合)  Advice  Aspectをモジュール化したもの。pecl-AOP ではコールバック関数で実装  Joinpoint  Adviceを織り込める場所。  weave  AdviceをJoinpointに差し込むこと。
  • 14.
    例外処理をAdvice化 function processError(AopJoinpoint $joinpoint){ try { return $joinpoint->process(); } catch (RuntimeException $e) { //エラー処理 } }
  • 15.
    Weave(織り込む) aop_add_around('A->*()', 'processError');  AクラスのすべてのメソッドにprocessError()を織り込む、という指令  これでAクラスのすべてのメソッドは、processError経由で呼ばれるよ うになる
  • 16.
    class A { function a() { try { doSomething(); //… } catch (RuntimeException $e) { processError($e); } } function b() { try { doSomething(); //… } catch (RuntimeException $e) { processError($e); } } function c() { try { doSomething(); //… } catch (RuntimeException $e) { processError($e); } } }
  • 17.
    class A { DRYになったね! function a() { doSomething(); //… } function b() { doSomething(); //… } function c() { doSomething(); //… } } aop_add_around('A->*()', function (AopJoinpoint $joinpoint) { try { return $joinpoint->process(); } catch (RuntimeException $e) { //エラー処理 } });
  • 18.
    対応Joinpoint  before anymethod / function call  after any method / function call  around any method / function call  During the arousing of an exception of any method / function  after any method / function call, should the method terminate normally or not (triggers an exception or not)
  • 19.
    応用例はいっぱいありそう  例外処理  関数キャッシュ 入出力のフィルタリング  ロギング  トランザクション  実行時間の計測  etc..
  • 20.
    関数キャッシュ  関数自体にキャッシュシステムを組み込む add_aop_around('A->*()', function (AopJoinpoint $joinpoint) { $key = $joinpoint->getClassName() . '->' . $joinpoint->getMethodName(); $cache = apc_fetch($key, $success); if ($success) { return $cache; } $result = $joinpoint->process(); apc_store($key, $result); return $result; });
  • 22.
    pecl-AOPのヤバいところ  既存の関数やメソッドなら何でも置き換 え可能  テストのモックとして強力
  • 23.
    rand()の固定化 aop_add_around('rand()', function (){ return 0; }); var_dump(rand()); var_dump(rand()); var_dump(rand());  rand()を同じ値しか返さない関数で置換  何度実行しても0を返す
  • 24.
    time()の固定化 aop_add_around('time()', function (){ return 0; }); var_dump(time());  time()も初期値を自由に変更できる  201X年を再現する、ということが可能  timecopの方が特化してて便利だけど… それに近いことが可能  https://github.com/hnw/php-timecop
  • 25.
    何でも置き換え  WebAPIにリクエストする部分を固定化 とか  DBに接続する部分を固定化とか  要はクラスの継承と無関係な継承・上書 きが可能  自由すぎてわけわからん  超強力 & 凶悪
  • 27.
    pecl-AOP面白いよ  超強力 & 凶悪  テストのお供に  書きにくいコードをすっきりDRYに  PHPのゆるさが5割増しになるのが悩ま しい
  • 28.
    注意点  まだbeta扱いです。  インストールもこけたりテストもこけた りする  segmentation faultもよく起きる  実戦投入はまだ危険