设计模式—命令模式:探索【命令模式】的奥秘与应用实践!

小明 2025-05-07 01:53:00 7

命令模式

命令���式是一种行为设计模式,它的主要目的是将请求封装成一个对象,从而使得请求的发送者和接收者之间进行解耦。

在命令模式中,命令被封装为一个对象,包含了需要执行的操作以及执行这些操作所需的所有参数。

命令的发送者不需要知道接收者的具体情况,也不需要知道命令如何被执行,只需要将命令对象发送给接收者,由接收者来解析并执行命令。

应用场景

  • 请求者创建命令,消费者根据命令动态做出响应的场景
  • 撤销和恢复操作:例如文本编辑器中的撤销和恢复功能。
  • 请求日志记录:可以记录用户操作的日志,以便后期查看。
  • 任务队列:例如线程池中的任务队列,可以将命令放入队列中异步执行。
  • 菜单项操作:例如图形界面中的菜单项单击、快捷键操作等。

    命令模式中的角色

    • 命令(Command): 命令是一个抽象的对象,封装了执行特定操作的方法。它通常包含一个执行操作的接口,可能还包含撤销操作的接口。
    • 具体命令(Concrete Command): 具体命令是命令的具体实现,它实现了命令接口中定义的方法。 每一个具体命令都与一个特定的接收者相关联,负责调用接收者执行请求的操作。
    • 接收者(Receiver): 接收者是实际执行命令操作的对象。它包含了命令执行时所需的具体逻辑。
    • 调用者/发送者(Invoker/Sender): 调用者是命令的发送者,它负责创建命令对象并将其发送给接收者。
    • 客户端(Client): 客户端创建具体命令对象,并将其与相应的接收者关联起来,然后将命令对象传递给调用者。

      优点

      • **解耦:**发送者和接收者之间的解耦,发送者不需要知道接收者的具体实现,只需要知道如何发送命令。
      • **扩展性:**易于添加新的命令和接收者,不会影响到已有的代码。
      • **支持撤销和重做操作:**可以通过保存命令历史来支持撤销和重做操作。

        缺点

        1. 可能导致类爆炸:为每个操作创建一个具体的命令类可能会导致类爆炸,尤其是在具有大量命令的系统中。
        2. 命令的逻辑混乱:如果命令的逻辑比较复杂,命令模式可能会导致命令的逻辑混乱。

        Java中的注意事项

        1. 合理的接口设计:命令接口应该设计得简洁清晰,易于使用。
        2. 抽象类的使用:可以使用抽象类来实现部分命令共同的行为,以避免重复代码。
        3. 命令的实现方式:根据业务需求选择合适的命令实现方式,如简单命令、宏命令等。
        4. 线程安全性:在多线程环境下使用命令模式时,需要考虑命令对象的线程安全性。

        1.案例1-小厨房(JavaSE版本)

        # 餐厅,服务员先根据客户创建订单,并将订单发送给厨师,厨师根据具体的订单生产
        

        1.1.创建命令接口

        /**
         * 抽象命令接口
         */
        public interface CookCommand {
        	/**
        	 * 执行命令
        	 */
        	void execute();
        }
        

        1.2.创建传输的参数

        import lombok.Getter;
        import lombok.Setter;
        import java.util.ArrayList;
        import java.util.List;
        @Getter @Setter
        public class Order {
        	// 订单数量
        	private final List orderList;
        	public Order() {
        		this.orderList = new ArrayList();
        	}
        	// 创建订单
        	public void createOrder(Menu menu){
        		orderList.add(menu);
        	}
        	// 获取订单
        	public List getOrderList(){
        		return orderList;
        	}
        	@Getter @Setter
        	static class Menu{
        		private String menuName; // 菜品名称
        		private Integer num; // 菜品数量
        	}
        }
        

        1.3.创建接收者

        import org.slf4j.Logger;
        import org.slf4j.LoggerFactory;
        import java.lang.invoke.MethodHandles;
        import java.util.List;
        /**
         * 命令接收人
         * @author 13723
         * @version 1.0
         * 2024/2/4 11:08
         */
        public class Cook {
        	private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
        	public void makeMenu(List menuList){
        		logger.info("-------------------------> 厨师准备开始做菜 
The End
微信