本日も読み飛ばしていきましょう!
どうも、限界派遣SESです。
最近はQiitanのために記事を書くことを日課にしてから「こんなクソ記事世の中にさらしてええんか・・・?」と葛藤しています。
そんなこんなで、ひとりアドカレ5日目で、そろそろ書くこと思いつかないなと思いつつ書いていきましょう。
本日はほとんどポエムです。
なぜか今まで知らなかったAOPの概念について書いていきます。
AOPとは?
AOPとは、アスペクト指向プログラミング(Aspect-Oriented Programming)のことです。
クロスカッティングな関心事を分離して云々と説明されるこれですが、なぜか今までこの概念を知らなかったです。
その理由はフレームワークがそもそもAOPを前提として実装されている事が多いということもあって、使っているのにそれがどういう設計思想で実現されているか?などを知らない事で気づいていなかったりします。
つまり結構身近な存在なのです。
AOPの基本概念
以下の4点が基本的な概念だそうです。
Aspect(アスペクト)
横断的関心事を定義する単位だそうです。
横断的関心事というと何を言っているのかわかりにくいですが、この横断的というのは「なんかいろんなとこで使いそうなヤツ」みたいな意味だと思っています。
- ログ記録
- ユーザーの権限チェック
- トランザクション管理
これらは様々な場所で呼ばれる事が予想されますよね。
これらをアスペクトとして定義します。
Join Point(ジョインポイント)
アスペクトを適用できるプログラムの特定箇所のことです。
具体的には以下のような箇所ですね。
- 関数呼び出し
- コンストラクタ呼び出し
- 関数終了
- 例外スロー
- フィールドアクセス
などがあります。
フィールドアクセスで呼び出される処理と言えばバリデーションチェックですね。
Advice(アドバイス)
アスペクトが具体的に何を行うか定義したものの事だそうです。
先ほどのアスペクトが関心事に対してこれは実際にどんな処理するんー?って感じですかね。
例えば「メソッドの前後には絶対にログをつける!」みたいな。
Pointcut(ポイントカット)
アスペクトを適用する具体的なジョインポイントを定義するルールだそう。
C#をやったことがある人なら以下の構文で理解できますね。具体的にどこにつけられるか?というのをAttribute
で定義できます。
// この属性が利用できる場所を定義
[AttributeUsage(AttributeTargets.Property)] // プロパティのみで利用できる
public class MyAttribute: Attribute{ ... }
これってデコレータでやってた処理じゃん
そうなんですよ。なので、本当に「なぜか今まで知らなかった」って気分です。
例えば、ログ記録であれば関数の開始と最後に必ずログを記録するという処理をしたりするわけです。
def hello_world():
logging.info(f"Function hello_world started")
print("Hello, world!")
logging.info(f"Function hello_world finished")
これは、先日のデコレータの話がまさにそれでした。
デコレーターを使うと以下のように記述できます。
@log
def hello_world():
print("Hello, world!")
ね、簡単でしょ?
つまり、私は今まで概念のみ何となく理解して、名称は知らずとも勝手にそれを実装したりなんだりをしてきたわけですね。
思えばDiscordBotを作り始めた頃からそれに触れてきたわけですが、概念として知ったのはつい先月(2024/11)のことでした。
あれ、初めてDiscordのBotを作ったのって3年前ぐらいじゃ・・・?
ともあれ、これにより言語ごとに「Go デコレータみたいなヤツ」という検索ワードではなく「Go AOP」のようにググれるようになったのはいいことです。
まとめ
ほぼ独学でプログラマを始めた私にとって、これらの概念は体感的に覚える事が多くなっていました。
それが悪いという訳ではないのですが、結果として共通言語的にそれを話す機会が失われるというのは少し惜しい気がします。
実際、私の知識は独学という事もあってアーキテクチャパターンなどにはかなり弱いです。毎回「これってどこに責任持たせるべきだろう?」となります。
そんなこんなで、やっぱり体系的に学びを得られる書籍はいいなー。と思う今日この頃でした。
おしまい