責任連鎖 (CoR) デザイン パターンは、バックエンド開発を大幅に強化できる強力な動作パターンです。このパターンでは、ハンドラーのチェーンを通じてリクエストを渡すことができ、各ハンドラーはリクエストを処理するか、次のハンドラーに渡すことができます。このブログでは、例として Java を使用して、バックエンドの観点から CoR パターンを調査し、特に Web サービスでのリクエストの検証と処理におけるアプリケーションに焦点を当てます。
Chain of Responsibility パターンは、リクエストが完了する前に複数の検証と処理ステップが必要となるバックエンド システムで特に役立ちます。たとえば、RESTful API では、メインのビジネス ロジックによって処理される前に、受信リクエストの認証、認可、データの整合性を検証する必要がある場合があります。これらのそれぞれの懸念事項は、チェーン内の異なるハンドラーによって処理できるため、責任とモジュール コードを明確に分離できます。このパターンは、さまざまなミドルウェア コンポーネントがリクエストを処理でき、特定の基準に基づいた柔軟な処理を可能にするミドルウェア アーキテクチャでも有益です。
CoR パターンは、ハンドラー、コンクリート ハンドラー、クライアントという 3 つの主要なコンポーネントで構成されます。 Handler は、リクエストを処理するためのインターフェイスを定義し、チェーン内の次のハンドラーへの参照を維持します。各 コンクリート ハンドラー は、特定の種類のリクエスト処理のロジックを実装し、リクエストを処理するか次のハンドラーに渡すかを決定します。 クライアントはリクエストをハンドラー チェーンに送信しますが、最終的にどのハンドラーがリクエストを処理するかは認識されません。この分離により、バックエンド システムの保守性と柔軟性が促進されます。
まず、次のハンドラーを設定し、リクエストを処理するためのメソッドを含む RequestHandler インターフェイスを定義します。
abstract class RequestHandler { protected RequestHandler nextHandler; public void setNext(RequestHandler nextHandler) { this.nextHandler = nextHandler; } public void handleRequest(Request request) { if (nextHandler != null) { nextHandler.handleRequest(request); } } }
次に、RequestHandler クラスを拡張する具体的なハンドラー クラスを作成します。各クラスはリクエスト処理の特定の側面を担当します。
class AuthenticationHandler extends RequestHandler { @Override public void handleRequest(Request request) { if (request.isAuthenticated()) { System.out.println("Authentication successful."); super.handleRequest(request); } else { System.out.println("Authentication failed."); request.setValid(false); } } } class AuthorizationHandler extends RequestHandler { @Override public void handleRequest(Request request) { if (request.isAuthorized()) { System.out.println("Authorization successful."); super.handleRequest(request); } else { System.out.println("Authorization failed."); request.setValid(false); } } } class DataValidationHandler extends RequestHandler { @Override public void handleRequest(Request request) { if (request.isDataValid()) { System.out.println("Data validation successful."); super.handleRequest(request); } else { System.out.println("Data validation failed."); request.setValid(false); } } } class BusinessLogicHandler extends RequestHandler { @Override public void handleRequest(Request request) { if (request.isValid()) { System.out.println("Processing business logic..."); // Perform the main business logic here } else { System.out.println("Request is invalid. Cannot process business logic."); } } }
次に、責任に基づいてハンドラーのチェーンを設定します:
public class RequestProcessor { private RequestHandler chain; public RequestProcessor() { // Create handlers RequestHandler authHandler = new AuthenticationHandler(); RequestHandler authzHandler = new AuthorizationHandler(); RequestHandler validationHandler = new DataValidationHandler(); RequestHandler logicHandler = new BusinessLogicHandler(); // Set up the chain authHandler.setNext(authzHandler); authzHandler.setNext(validationHandler); validationHandler.setNext(logicHandler); this.chain = authHandler; // Start of the chain } public void processRequest(Request request) { chain.handleRequest(request); } }
クライアント コードがリクエスト処理チェーンとどのようにやり取りするかを次に示します:
public class Main { public static void main(String[] args) { RequestProcessor processor = new RequestProcessor(); // Simulating a valid request Request validRequest = new Request(true, true, true); processor.processRequest(validRequest); // Simulating an invalid request Request invalidRequest = new Request(true, false, true); processor.processRequest(invalidRequest); } }
リクエスト データをカプセル化するために使用される単純なリクエスト クラスは次のとおりです。
class Request { private boolean authenticated; private boolean authorized; private boolean dataValid; private boolean valid = true; public Request(boolean authenticated, boolean authorized, boolean dataValid) { this.authenticated = authenticated; this.authorized = authorized; this.dataValid = dataValid; } public boolean isAuthenticated() { return authenticated; } public boolean isAuthorized() { return authorized; } public boolean isDataValid() { return dataValid; } public boolean isValid() { return valid; } public void setValid(boolean valid) { this.valid = valid; } }
クライアント コードを実行すると、次の出力が表示されます:
Authentication successful. Authorization successful. Data validation successful. Processing business logic... Authentication successful. Authorization failed. Request is invalid. Cannot process business logic.
懸念事項の分離: 各ハンドラーには明確な責任があるため、コードの理解と保守が容易になります。この分離により、チームはワークフロー全体を気にすることなく、リクエスト処理の特定の側面に集中できるようになります。
柔軟なリクエスト処理: 既存のロジックを変更せずにハンドラーを追加または削除できるため、新しい要件やビジネス ルールの変更に簡単に適応できます。このモジュール性はアジャイル開発実践をサポートします。
保守性の向上: ハンドラーの分離された性質により、1 つのハンドラーでの変更 (検証ロジックの更新など) が他のハンドラーに影響を与えず、システムにバグが侵入するリスクが最小限に抑えられます。 &&&]
テストの簡素化: 個々のハンドラーを個別にテストできるため、テスト プロセスが簡素化されます。これにより、対象を絞った単体テストと、特定のリクエスト処理ステップのより簡単なデバッグが可能になります。
パフォーマンス オーバーヘッド: ハンドラーの長いチェーンにより、特に多くのチェックを順番に実行する必要がある場合、待ち時間が発生する可能性があります。パフォーマンスが重要なアプリケーションでは、これが問題になる可能性があります。
フロー制御の複雑さ: このパターンは個々のハンドラーの責任を簡素化しますが、リクエスト処理の全体的なフローが複雑になる可能性があります。複数のハンドラーを通じてリクエストがどのように処理されるかを理解するには、追加のドキュメントと新しいチーム メンバーの労力が必要になる場合があります。
責任連鎖パターンは、懸念事項の分離、柔軟性、保守性を促進することでリクエスト処理を強化する、バックエンド開発における効果的な設計パターンです。リクエストの検証と処理にこのパターンを実装することで、開発者はさまざまな要件を効率的に処理できる堅牢でスケーラブルなシステムを作成できます。 RESTful API、ミドルウェア処理、その他のバックエンド アプリケーションのいずれであっても、CoR パターンを採用すると、よりクリーンなコードと改善されたアーキテクチャ設計につながり、最終的にはより信頼性が高く保守しやすいソフトウェア ソリューションが実現します。
免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。
Copyright© 2022 湘ICP备2022001581号-3