定義:
リクエストをオブジェクトとしてカプセル化して、さまざまなリクエストで顧客をパラメータ化したり、リクエストをキューに入れたり、リクエストログを記録したり、リバーシブル操作をサポートしたりできるようにします。
構造:(本の中の写真、侵入と削除)
抽象コマンドクラス
いくつかの特定のコマンドクラス
特定の実行順序の受信者クラス
呼び出し元
クライアントクラスはありません。すべてのリクエストはメッセージクラスを介して直接行われます。
例:
注文に関しては、皇帝のことを考えてから、通常は複数の顧客のことを考えますが、皇帝には1人しかいませんが、重要ではありません。要点はここにはありません。
皇帝の命令は通常、彼の周りの尼僧の首長に直接伝えられ、彼は直接命令を与える人を見つけることができず、彼はその下の尼僧を本当に知らないかもしれません。
だから...コマンドモードもここに適しています。
私はいくつかの変更を加えました。最初にコードを貼り付けてから、詳しく説明します。
パレスガールズ(受取人):
package designpattern.command;
/*
* 宫女
*/
public class Maid {
String name;
public Maid(String name) {
this.name = name;
}
public void clean() {
System.out.println(this.name + ":打扫卫生");
}
}
Eunuch(受信者):
package designpattern.command;
/*
* 太监
*/
public class Eunuch {
String name;
public Eunuch(String name) {
this.name = name;
}
public void carrySedanChair() {
System.out.println(this.name + ":抬轿子");
}
}
抽象コマンドインターフェイス:
package designpattern.command;
public interface Command {
public void execute();
}
クリーニングコマンドクラス(特定のコマンドクラス):
package designpattern.command;
public class CleanCommand implements Command {
private Maid maid;
public CleanCommand(Maid maid) {
this.maid = maid;
}
@Override
public void execute() {
maid.clean();
}
}
セダンリフトコマンドクラス(特定のコマンドクラス):
package designpattern.command;
public class CarrySedanChairCommand implements Command {
private Eunuch eunuch;
public CarrySedanChairCommand(Eunuch eunuch) {
this.eunuch = eunuch;
}
@Override
public void execute() {
eunuch.carrySedanChair();
}
}
Eunuchチーフ(発動者):
package designpattern.command;
import java.util.ArrayList;
import java.util.List;
public class ManagerEunuch {
private List<Command> commands = new ArrayList<Command>();
public void setCommand(Command command) {
this.commands.add(command);
}
public void notifyIt() {
for (Command command : commands) {
command.execute();
}
}
}
クライアント:
package designpattern.command;
public class Client {
public static void main(String[] args) {
Maid xiaocui = new Maid("小翠");
Maid xiaohua = new Maid("小花");
Eunuch xiaozhuozi = new Eunuch("小卓子");
Eunuch xiaoguizi = new Eunuch("小贵子");
Command cleanCommand1 = new CleanCommand(xiaocui);
Command cleanCommand2 = new CleanCommand(xiaohua);
Command carrySedanChairCommand1 = new CarrySedanChairCommand(xiaozhuozi);
Command carrySedanChairCommand2 = new CarrySedanChairCommand(xiaoguizi);
ManagerEunuch ligongong = new ManagerEunuch();
ligongong.setCommand(cleanCommand1);
ligongong.setCommand(cleanCommand2);
ligongong.setCommand(carrySedanChairCommand1);
ligongong.setCommand(carrySedanChairCommand2);
ligongong.notifyIt();
}
}
結果出力:
コミドリ: 花の掃除: 小さなzhuoziの掃除:セダンの椅子 小さなタカコ:セダンの椅子
もともと注文の受け手はいろいろあるべきだと思っていたのですが、例えば私の例では、法廷の女性や尼僧がいます。でも、実はこれは一人のパフォーマーに向いていると思います。
私は複数のエグゼキュータを実装しましたが、エグゼキュータと特定のコマンドは密接に関連しています。たとえば、クリーニングコマンド(CleanCommand)には、コートレディ(エグゼキュータ)のインスタンスがあります。
eunuchがクリーンアップする場合は、eunuchのインスタンスを使用して別のクリーニングコマンドクラスを作成する必要があります。executorの親クラスを抽象化して、すべてにこの親クラスのインスタンスを保持させることはできますが、father.clean()を呼び出すことはできません。親クラスでこのメソッドを定義しない限り、子クラスがメソッドを追加するたびに、それに応じて親クラスを増やす必要があります。これは明らかに適切な設計ではありません。この問題を解決する良い方法を考えていなかったので、単一のタイプのパフォーマーに適しているのではないかと思います。
エム、もう一度考えてみました。私の例では、実行者の分類に問題がある可能性があります。各実行者の作業範囲がかなり異なる可能性があります。たとえば、私の例では、宮殿の女性と尼僧の50%がいる可能性があります。仕事が重なっているので、インペリアルダイニングルームやランドリールームなど、特定の種類の仕事に分類すれば問題ありません。それは思考の誤解と見なすことができます。レッスンを学ぶ。
総括する:
本に書かれている点はかなり良いと思いますので、ここで引用しましょう。
まず、コマンドキューを簡単に設計できます。
次に、必要なときにコマンドをログに記録する方が簡単です。
第三に、リクエストを受け取った当事者がリクエストを拒否するかどうかを決定できるようにします
第4に、リクエストを簡単にキャンセルしてやり直すことができます。
第5に、新しい特定のコマンドクラスを追加しても他のクラスには影響しないため、新しい特定のコマンドクラスを簡単に追加できます。
主な利点は、コマンドモードが、操作を要求するオブジェクトを、操作の実行方法を知っているオブジェクトから分離することです。