デザインパターン コマンドパターン 注意事項
説明する
デザインパターン・コマンドパターンの学習の書き方を記録します。使用される JDK バージョンはバージョン 1.8 です。
指示
目的: リクエストをオブジェクトとしてカプセル化し、クライアントをさまざまなリクエストでパラメータ化できるようにし、リクエストのキューイングやロギング、および元に戻せる操作のサポートを可能にします。
構造:
で:
- コマンドは、操作を実行するためのインターフェイスを宣言します。
- ConcreteCommand は、レシーバー オブジェクトをアクションにバインドし、レシーバーの対応する操作を呼び出して Execute を実装します。
- クライアントは特定のコマンド オブジェクトを作成し、その受信者を設定します。
- 実行者はコマンドにこのリクエストを実行するように要求します。
- 受信者は、リクエストの実行に関連する操作を実行する方法を知っています。どのクラスも受信側として機能できます。
適用性:
- システムは、呼び出し元と受信者が直接対話しないように、リクエストの呼び出し元とリクエストの受信者を切り離す必要があります。
- システムはリクエストを指定し、キューに入れて、異なる時間に実行する必要があります。
- システムは、コマンドの取り消しおよび復元操作をサポートする必要があります。
目次
コマンドパターン例のクラス図
この UML クラス図を使用して、コマンド パターンの例を実装します。
注文タイプ
package com.example.deesign_patterns.command;
import java.util.HashMap;
import java.util.Map;
//订单类
public class Order {
//餐桌号码
private int diningTable;
//所下的餐品及份数
private Map<String,Integer> foodDir=new HashMap<String,Integer>();
public int getDiningTable() {
return diningTable;
}
public void setDiningTable(int diningTable) {
this.diningTable = diningTable;
}
public Map<String, Integer> getFoodDir() {
return foodDir;
}
public void setFoodDir(String name,int num) {
foodDir.put(name,num);
}
}
シェフ部門
package com.example.deesign_patterns.command;
//厨师类
public class SeniorChef {
public void makeFood(String name,int num){
System.out.println(num+"份"+name);
}
}
抽象コマンドクラス
package com.example.deesign_patterns.command;
//抽象命令类
public interface Command {
void execute();
}
オーダーコマンドクラス
package com.example.deesign_patterns.command;
import java.util.Map;
import java.util.Set;
//订单命令类,具体的命令类
public class OrderCommand implements Command{
//持有接收者对象
private SeniorChef seniorChef;
private Order order;
public OrderCommand(SeniorChef seniorChef, Order order) {
this.seniorChef = seniorChef;
this.order = order;
}
@Override
public void execute() {
System.out.println(order.getDiningTable()+"桌的订单:");
Map<String,Integer> foodDir=order.getFoodDir();
//遍历map集合
Set<String> keys=foodDir.keySet();
for(String foodName:keys){
seniorChef.makeFood(foodName,foodDir.get(foodName));
}
System.out.println(order.getDiningTable()+"桌的饭准备完毕!!!");
}
}
ウェイタータイプ
package com.example.deesign_patterns.command;
import java.util.ArrayList;
import java.util.List;
//服务员类,属于请求者角色
public class Waiter {
//持有多个命令对象
private List<Command> commands=new ArrayList<Command>();
public void setCommand(Command cmd){
//将cmd对象存储到list集合中
commands.add(cmd);
}
//发起命令功能 喊订单来了
public void orderUp(){
System.out.println("美女服务员:大厨,新订单来了。。。。");
//遍历list集合
for(Command command:commands){
if(command!=null){
command.execute();
}
}
}
}
テストクラス
package com.example.deesign_patterns.command;
//测试类
public class Client {
public static void main(String[] args) {
//创建第一个订单对象
Order order1=new Order();
order1.setDiningTable(1);
order1.setFoodDir("西红柿鸡蛋面",1);
order1.setFoodDir("小杯可乐",2);
//创建第二个订单对象
Order order2=new Order();
order2.setDiningTable(2);
order2.setFoodDir("尖椒肉丝盖饭",1);
order2.setFoodDir("小杯雪碧",1);
//创建厨师对象
SeniorChef seniorChef=new SeniorChef();
//创建命令对象
OrderCommand cmd1=new OrderCommand(seniorChef,order1);
OrderCommand cmd2=new OrderCommand(seniorChef,order2);
//创建调用者(服务员对象)
Waiter invoke=new Waiter();
invoke.setCommand(cmd1);
invoke.setCommand(cmd2);
//让服务员发起命令
invoke.orderUp();
}
}
利点:
- システムの結合を減らします。コマンド パターンは、操作を実行するオブジェクトから操作を呼び出すオブジェクトを分離します。
- コマンドの追加や削除はとても便利です。コマンド モードを使用してコマンドを追加および削除しても、他のクラスに影響を与えることはなく、開始および終了の原則を満たしており、拡張の柔軟性が高くなります。
- マクロコマンドを実装することができます。コマンド モードを組み合わせモードと組み合わせて、複数のコマンドを組み合わせて 1 つのコマンド、つまりマクロ コマンドにまとめることができます。
- 元に戻す操作と復元操作を便利に実装します。コマンドモードは、後に導入するメモモードと組み合わせることで、コマンドの取り消しや復元を実現できます。
欠点:
- コマンド モードを使用すると、一部のシステムで特定のコマンド クラスが多すぎる場合があります。
- システム構造はさらに複雑です。