リクエストはオブジェクトにカプセル化されるため、さまざまなリクエストを使用してクライアントをパラメータ化したり、リクエストをキューに入れたり、リクエストログを記録したりできます。これにより、コマンドのキャンセルおよび回復機能を提供できます。
たとえば、司令官は兵士に何かをするように命じました。全体の観点から、司令官の役割はパスワードを発行することであり、パスワードは兵士の耳に渡され、兵士はそれを実行します。このプロセスの良いところは、3つが互いに分離されていることです。どちらの当事者も他の当事者に依存する必要はなく、独自のことを行うだけで済みます。司令官は、兵士のやり方ではなく、結果を求めています。
クラス図
コード例
1. class Invoker {
2. private Command command;
3. public void setCommand(Command command) {
4. this.command = command;
5. }
6. public void action(){
7. this.command.execute();
8. }
9. }
10.
11. abstract class Command {
12. public abstract void execute();
13. }
14.
15. class ConcreteCommand extends Command {
16. private Receiver receiver;
17. public ConcreteCommand(Receiver receiver){
18. this.receiver = receiver;
19. }
20. public void execute() {
21. this.receiver.doSomething();
22. }
23. }
24.
25. class Receiver {
26. public void doSomething(){
27. System.out.println("接受者-业务逻辑处理");
28. }
29. }
30.
31. public class Client {
32. public static void main(String[] args){
33. Receiver receiver = new Receiver();
34. Command command = new ConcreteCommand(receiver);
35. //客户端直接执行具体命令方式(此方式与类图相符)
36. command.execute();
37.
38. //客户端通过调用者来执行命令
39. Invoker invoker = new Invoker();
40. invoker.setCommand(command);
41. invoker.action();
42. }
43. }
コードから、呼び出すときの実行のタイミングは、最初に呼び出し元クラス、次にコマンドクラス、最後に受信者クラスであることがわかります。つまり、コマンドの実行は3つのステップに分割され、その結合はクラス内のすべての操作をカプセル化するよりもはるかに低く、これがコマンドモードの本質です。コマンドの呼び出し元です。実行者とは別にして、両方の当事者が相手の操作方法を気にする必要がないようにします。
コマンドモードの目的は、コマンドの発行者と実行者の間の分離を実現し、要求と実行の分離を実現することです。Strutsに精通している学生は、Strutsが実際には要求とプレゼンテーションを分離するテクノロジーであり、コマンドモードを必要とすることを知っておく必要があります。思想!
コマンドパターンの構造
名前が示すように、コマンドモードはコマンドのカプセル化です。まず、コマンドモードのクラス図の基本構造を見てみましょう。
- コマンドクラス:実行する必要のあるコマンドを宣言する抽象クラスです。一般的に、executeメソッドはコマンドを実行するために公に発表されます。
- ConcreteCommandクラス:抽象クラスで宣言されたメソッドを実装するCommandクラスの実装クラス。
- クライアントクラス:最後のクライアント呼び出しクラス。
上記の3つのクラスの役割は比較的理解しやすいはずです。ここでは、InvokerクラスとRecevierクラスに焦点を当てましょう。
- 呼び出し元のクラス:呼び出し側、コマンドを呼び出すための責任を負います。
- レシーバークラス:レシーバー。コマンドの受信と実行を担当します。
率直に言って、コマンドのいわゆるカプセル化は、一連の操作をメソッドに書き込むだけであり、クライアントがそれを呼び出すには、クラス図に反映され、ConcreteCommandクラスとClientクラスのみがコマンドを完了できます。カプセル化は、さらに進んだとしても、柔軟性を高めるために、適切な抽象化のために別のCommandクラスを追加できます。呼び出し元と受信者の役割は何ですか。
実際、別の角度から考えることができます。一部の操作を他の操作が呼び出すコマンドとして単純にカプセル化した場合、どのようにモードと呼ぶことができますか?動作モードとしてのコマンドモードは、最初に低結合である必要があります。結合度が低い場合にのみ、柔軟性を向上させることができます。発信者と受信者の2つの役割を結合する目的は、まさにこれです。
コマンドモードの長所と短所
まず、コマンドモードのカプセル化は非常に優れています。各コマンドはカプセル化されており、クライアントの場合、コマンドの実行方法を知らなくても、対応するコマンドを呼び出すために必要な関数は何ですか。たとえば、ファイル操作コマンドのセットがあります:新しいファイル、ファイルのコピー、ファイルの削除。これらの3つの操作が1つのコマンドクラスにカプセル化されている場合、クライアントはこれらの3つのコマンドクラスがあることを知る必要があるだけです。コマンドクラスにカプセル化されているロジックについては、クライアントは知る必要はありません。
第二に、コマンドモードは非常に拡張可能です。コマンドモードでは、レシーバークラスは通常、最も基本的な操作をカプセル化し、コマンドクラスはこれらの基本的な操作を再カプセル化します。新しいコマンドを追加する場合、コマンドクラスの記述は、通常、最初から開始することはありません。呼び出すレシーバークラスが多数あり、呼び出すコマンドクラスも多数あるため、コードの再利用性は非常に優れています。たとえば、ファイル操作では、ファイルを切り取るコマンドを追加する必要があり、ファイルのコピーと削除の2つのコマンドを組み合わせるだけでよいので、非常に便利です。
最後に、コマンドモードの欠点について説明します。つまり、コマンドが多いと、開発の頭痛の種になります。特に、多くの単純なコマンドは数行のコードで実装されます。コマンドモードを使用する場合、コマンドがどれほど単純であっても、それをカプセル化するコマンドクラスを作成する必要があります。
コマンドモードの該当するシナリオ
ほとんどの要求応答モード機能では、コマンドモードを使用する方が適しています。コマンドモードの定義にあるように、コマンドモードは、ログ記録や操作のキャンセルなどの機能を実装するのに便利です。