AOP の紹介AOP (アスペクト指向プログラミング) の主な機能は、コアビジネスロジックモジュールに関連しないいくつかの機能を抽出することです。ビジネスロジックに関連しないこれらの機能には、通常、ログ統計、セキュリティ制御、例外処理などが含まれます。これらの関数は抽出された後、「動的ウィービング」を通じてビジネス ロジック モジュールに統合されます。 アスペクト指向プログラミングは、ターゲットロジックを変更せずに既存の関数またはオブジェクトにコードを挿入する方法を提供します。 必須ではありませんが、挿入されたコードは、ログ機能の追加、メタデータのデバッグ、または他のあまり一般的ではないが追加の動作など、横断的な関心事を持つことを意図しており、元のコードの内容に影響を与えずに挿入できます。 良い例を挙げると、ビジネス ロジックを作成したが、ログ記録コードを追加していないことに気付いたとします。通常のアプローチは、ログ記録ロジックを新しいモジュールに集中させ、機能ごとにログ記録情報を追加することです。 ただし、ログに記録する各メソッドの実行の特定の時点で、同じロガーに 1 行のコードを挿入することができれば、作業は間違いなくずっと簡単になります。そうじゃない? 側面、アドバイス、ポイントカット(何、いつ、どこ)上記の定義をより正式なものにするために、ロガーを例にとり、AOP に関する 3 つの概念を紹介しましょう。このパラダイムをさらに探求することに決めた場合は、次のものが役立ちます。
この説明を読めば、既存の OOP ベースのビジネス ロジックにログ記録ロジックを追加するための AOP ベースのライブラリを作成するのは比較的簡単であることがわかるはずです (例)。必要なのは、ターゲット オブジェクトの既存の一致メソッドを、適切なタイミングでアスペクト ロジックを追加して元のメソッドを呼び出すカスタム関数に置き換えることだけです。 基本的な実装私は視覚的に学習するタイプなので、AOP ベースの動作を追加するための 次の例では、実装がいかに簡単か、そしてコードにどのような利点をもたらすかを説明します。 `/** オブジェクト内のすべてのメソッドを取得するためのヘルパー関数*/ const getMethods = (obj) => Object.getOwnPropertyNames(Object.getPrototypeOf(obj)).filter(item => typeof obj[item] === 'function') /** アドバイスが指示したときにアスペクトを呼び出すカスタム関数で元のメソッドを置き換えます */ function replaceMethod(target, methodName, aspect, advice) { const originalCode = target[methodName] target[methodName] = (...args) => { if(["before", "around"].includes(advice)) { aspect.apply(target, args) } const returnedValue = originalCode.apply(target, args) if(["after", "around"].includes(advice)) { aspect.apply(target, args) } if("afterReturning" == advice) { return aspect.apply(target, [returnedValue]) } else { return returnedValue } } } module.exports = { // エクスポートの主な方法: 必要なときに必要な場所にアスペクトをターゲットに注入する inject: function(target, aspect, advice, pointcut, method = null) { if(pointcut == "method") { if(method != null) { replaceMethod(target, method, aspect, advice) } else { throw new Error("メソッドにアスペクトを追加しようとしましたが、メソッドが指定されていません") } } if(pointcut == "methods") { const methods = getMethods(target) methods.forEach( m => { replaceMethod(target, m, aspect, advice) }) } } }` 非常に簡単です。前述したように、上記のコードはすべてのユースケースをカバーしているわけではありませんが、次の例をカバーするには十分なはずです。 しかし、先に進む前に、 次に、このライブラリの使い方を説明します。 `const AOP = require("./aop.js") クラス MyBusinessLogic { 追加(a, b) { console.log("add を呼び出しています") a + bを返す } 連結(a, b) { console.log("concat を呼び出しています") a + bを返す } パワー(a, b) { console.log("パワーを呼び出し中") a ** b を返す } } const o = 新しい MyBusinessLogic() function loggingAspect(...args) { console.log("== ロガー関数を呼び出しています ==") console.log("受け取った引数: " + args) } function printTypeOfReturnedValueAspect(value) { console.log("返された型: " + typeof value) } AOP.inject(o,loggingAspect,"before","methods") AOP.inject(o,printTypeOfReturnedValueAspect,"afterReturning","methods") o.add(2,2) o.concat("こんにちは", "さようなら") o.power(2, 3)` これは 3 つのメソッドを持つ単なる基本オブジェクトであり、特別なものではありません。 2 つの汎用的なアスペクトを挿入します。1 つは受信プロパティをログに記録するためのもので、もう 1 つは戻り値を分析してその型をログに記録するためのものです。 2 つの側面、2 行のコード (6 行である必要はありません)。 これで例は終了です。出力は次のようになります。
AOPの利点AOP の概念と目的がわかったら、アスペクト指向プログラミングを使用する理由を推測できるかもしれませんが、簡単にまとめてみましょう。
AOPの主な問題点すべてが完璧というわけではないので、このパラダイムには批判的な人もいます。 彼らが提起する主な問題は、その主な利点が実際にはコードのロジックと複雑さを隠すことであり、それが明確でない場合に副作用が生じる可能性があるということです。 よく考えてみると、彼らの言うことはもっともです。AOP は、既存のメソッドに無関係な動作を追加したり、ロジック全体を置き換えたりする大きな力を与えてくれます。もちろん、これがこのパラダイムが導入された正確な理由ではないかもしれませんし、私が上で示した例の意図では決してありませんでした。 ただし、やりたいことは何でもできるので、適切なプログラミング手法を理解していないと、非常に大きな混乱を招く可能性があります。 決まり文句に聞こえないように、ベンおじさんの言葉を言い換えます。 大いなる力には大いなる責任が伴う AOP を正しく使用するには、ソフトウェア開発のベスト プラクティスを理解する必要があります。 私の意見では、このツールを使用すると多くの害を及ぼす可能性があるからといって、それが悪いツールだというわけではありません。多くの利点ももたらします (つまり、多くの共通ロジックを一元化された場所に抽出し、必要な場所に 1 行のコードでそれを挿入できます)。私にとって、これは学ぶ価値があり、間違いなく使用する価値のある強力なツールです。 アスペクト指向プログラミングは OOP を完璧に補完するものであり、特に JavaScript の動的な性質のおかげで、非常に簡単に実装できます (ここのコードで実証されているように)。大量のロジックをモジュール化および分離し、後でそのロジックを他のプロジェクトと共有するための強力な機能を提供します。 もちろん、正しく使用しないと、大変なことになります。しかし、これを使用すると、多くのコードを簡素化およびクリーンアップできることは間違いありません。これが AOP に関する私の意見ですが、あなたはどう思いますか? AOPって聞いたことありますか?以前に使ったことがありますか?ぜひ下記にコメントを残してあなたの考えを共有してください! JavaScript での AOP プログラミングに関するこの記事はこれで終わりです。より関連性の高い js AOP プログラミング コンテンツについては、123WORDPRESS.COM で以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後も 123WORDPRESS.COM を応援していただければ幸いです。 以下もご興味があるかもしれません:
|
<<: Python 仮想環境のインストールとアンインストールの方法と発生する問題
>>: Spark SQL の 4 つの一般的なデータ ソースの詳細な説明
Zabbix バージョン 3.0 以降、Zabbix サーバー、Zabbix プロキシ、Zabbix...
楽観的ロック楽観的ロックは、主にデータ バージョン記録メカニズムに基づいて実装され、通常はデータベー...
Mysql マスタースレーブ同期の Last_IO_Errno:1236 エラーの原因は何ですか? ...
目次1. テーブル自動ソート2. ページング機能3.el-checkbox-group 複数選択ボッ...
以前、単純な UDP サーバーとクライアントの例を書きましたが、その中で、自分自身をクライアントと見...
解決策は2つあります。 1つはCSSで、background-size:coverを使用して画像の伸...
目次1. コンポーネント通信1. Props 親コンポーネント ---> 子コンポーネント通信...
1. CSS3の三角形は特殊効果でズームし続けます11.1 画像プレビュー 11.2 index.h...
MySQL レプリケーション テーブルの詳細な説明テーブル構造、インデックス、デフォルト値などを含む...
目次遷移フック関数カスタム遷移クラス名遷移グループの使用まとめまずは例を見てみましょうコードは次のと...
この記事では、天気予報機能を実現するためのVueの具体的なコードを参考までに共有します。具体的な内容...
面接には必需品、仕事でも必ず使います。うーん、誰でも分かるでしょう。これ以上何も言わずに、要約とレン...
序文以前フロントエンドを勉強していたとき、メタタグに対する私の理解はこの一文だけでした。 <メ...
この記事では、MySQL 5.7.21のインストールに関する注意事項をまとめ、皆さんと共有します。 ...
Jenkins はオープンソース ソフトウェア プロジェクトです。Java をベースに開発された継続...