本文最后更新于 2025年7月26日 晚上
命令模式将请求封装成对象,以便使用不同的请求,日志,队列等来参数化其他对象
角色
- 客户端 : 创建一个具体命令对象,并确定其接收者
- 命令 : 声明了一个给所有具体命令类的接口对象
- 具体命令 :定义一个接收者和行为之间的弱耦合,实现execute()方法,并负责调用接收者的相应操作
- 请求者:负责调用命令对象执行请求
- 接收者:负责具体实施和执行一个请求
场景
- 请求需要排队或日志记录的系统(如任务调度系统)
- 需要支持操作撤销/重做(如编辑器、事务系统)
- 需要将行为抽象成参数进行传递(如菜单栏、按钮绑定操作)
优点
- 命令模式中,请求者不直接与接收者交互,即请求者不包含接收者的引用,因此彻底消除了彼此之间的耦合
- 命令模式满足“开闭”原则。如果增加信的具体命令和该命令的接收者,不必修改调用者的代码,调用者就可以使用新的命令对象
- 由于请求者被封装到了命令中,那么就可以将具体命令保存到持久化的媒介中,在需要的时候,重新执行这个具体命令
- 使用命令模式可以对请求者的请求排队,每个请求对应一个具体命令
缺点
可能产生大量具体命令类
实现命令模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
| public class Barbecuer { public void bakeMutton(){ System.out.println("烤羊肉串"); } public void bakeChickenWing(){ System.out.println("烤鸡翅"); } }
public abstract class Command{ protected Barbecuer barbecuer ;
public Command(Barbecuer barbecuer){ this.barbecuer = barbecuer ; }
public abstract void execute(); }
public class BakeChickenWingCommand extends Command { public BakeChickenWingCommand(Barbecuer barbecuer){ super(barbecuer); }
@Override public void execute(){ barbecuer.bakeChickenWing(); } }
public class BakeMuttonCommand extends Command{ public BakeMuttonCommand(Barbecuer barbecuer){ super(barbecuer); }
@Override public void execute(){ barbecuer.bakeMutton(); } }
public class Waiter{ private List<Command>commandList = new ArrayList<>();
public void addCommand(Command command){ commandList.add(command); } public void notifyBarbecuer(){ for(Command command:commandList){ command.execute(); } } }
public class Test{ public static void main(String[] args){ Barbecuer barbecuer = new Barbecuer(); Waiter waiter = new waiter();
waiter.addCommand(new BakeChickenWingComand(barbecuer)); waiter.addCommand(new BakeMuttonCommand(barbecuer));
waiter.notifyBarbecuer(); } }
|
总结
命令模式是一种将“动作的请求者”与“动作的执行者”彻底解耦的行为型设计模式。它通过将操作请求封装为对象,使得请求本身可以被排队、记录、撤销,甚至在分布式系统中跨网络传递。