TypeScript: デコレータでAOPのようなロギング。
手元にずっととってあったメモ。そんなに変なことを書いていなかったのでブログとして公開してみる。
デコレータとは
A Decorator is a special kind of declaration that can be attached to a class declaration, method, accessor, property, or parameter. Decorators use the form @expression, where expression must evaluate to a function that will be called at runtime with information about the decorated declaration.
TypeScriptのDecoratorについて - 公式ドキュメント日本語訳
クラスの宣言やメソッド、アクセサ、プロパティ、パラメーター に付与できる特別な宣言。見た目、機能、付与できる部分などがJava/Kotlinのアノテーションに似ている。
デコレータの使いみち
ビジネスロジックをもつクラス、メソッドのうち、ロギング・キャッシュなどの機能を剥がすことでクラスやメソッドの責務をより明確にさせることができる(関心事の分離)。トレースログのような、各レイヤごとに共通でやりたいことをアスペクトで切ってまとまった処理にすることができる。
自分がJVMを母語とするプログラマで、Springの大規模フレームワークに体が慣れているから、そういった機能を欲するというのもあると思う。
共通ロギング
使いみちのうち、最もポピュラー?なロギングをデコレータによって実現する。
前提条件として、デコレータといいつつもメソッドの付与してメソッドのメタデータを動的に取得する、リフレクションとも組み合わせて実現することになる。
デコレータになるメソッドのシグネチャ:
const trace = (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {
}
descriptor.value
にアクセスすることで、デコレータが付与されているメソッドを直接参照できる。この性質を利用して、一度 descriptor.value
を変数にとっておき、その後上書きしながら実行する関数に処理を動的に挟み込むようにする。
参考
デコレータについて