从开源框架理解设计模式系列#Command命令模式

本文详细介绍了Command命令模式,包括模式的定义、为何需要使用以及如何实现。通过实例分析了命令模式在Dubbo和Tomcat中的应用,展示了命令模式如何降低系统耦合度,提高扩展性。同时讨论了命令模式的优缺点,如易于实现请求的撤销和重做,但也可能导致命令类的数量增加。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

what什么是命令模式

why为什么需要命令模式

how如何实现命令模式

ACTIVE OBJECT 模式

开源框架经典案例

Dubbo中使用的命令模式

ls 列出消费者和提供者

Offline 下线服务命令

Tomcat命令模式

使用场景

优缺点对比

优点

缺点

参考资料 


what什么是命令模式

        Gof定义:将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤消的操作。其别名为动作(Action)模式或事务(Transaction)模式。

        HeadFirst定义:将“请求”封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象。命令模式也支持可撤销的操作。

why为什么需要命令模式

        命令模式可以对发送者和接收者完全解耦,发送者与接收者之间没有直接引用关系,发送请求的对象只需要知道如何发送请求,而不必知道如何完成请求。这就是命令模式的模式动机。

        在现实生活中,遥控器就是一个典型的命令模式,我们只需要按一下遥控器就可以执行切台调音等等功能。想想如果没有遥控器的话,我们需要去理解不同电视的设置,不同电视的调节模式。

        这里先引用设计模式原版里面的解释,为什么需要命令模式。

        有时候必须向某对象提交请求,但是并不知道请求操作或请求的接受者的信息。例如,用户界面工具箱包括按钮和菜单这样的对象,他们执行请求响应用户输入。但工具箱不能显示的在按钮或菜单中实现,因此只有使用工具箱的应用指导该由那个对象做哪个操作。而工具箱的设计者无法指导请求的接受者或执行的操作。

        命令模式通过将请求本身变成一个对象来使工具箱对象可向未指定的应用对象提出请求。这个对象可被存储并像其他的对象一样被传递。这一模式的关键是一个抽象的Command类,它定义了一个执行操作的接口。其最简单的形式是一个抽象的Excute操作。具体的Command子类将接收者作为其一个实例变量,并实现Excute操作,指定接收者采取的动作。而接收者有执行该请求所需的具体信息。

how如何实现命令模式

        命令模式包含以下主要角色。

  1. 抽象命令类(Command)角色:声明执行命令的接口,拥有执行命令的抽象方法 execute()。
  2. 具体命令类(Concrete Command)角色:是抽象命令类的具体实现类,它拥有接收者对象,并通过调用接收者的功能来完成命令要执行的操作。
  3. 实现者/接收者(Receiver)角色:执行命令功能的相关操作,是具体命令对象业务的真正实现者。
  4. 调用者/请求者(Invoker)角色:是请求的发送者,它通常拥有很多的命令对象,并通过访问命令对象来执行相关请求,它不直接访问接收者。

命令模式的结构图


命令模式的结构图

ACTIVE OBJECT 模式

        Active Object是之前看敏捷软件开发这本书里面看到的,Martin大叔说这是他最喜欢的Command之一,也是实现多线程控制的古老技术,看完以后其实会发现,我擦,这不就是Reactor模式思想,的这里我们就来分析一下,先引用并发编程网对active object的描述。

Active Object模式是一种异步编程模式。它通过对方法的调用(Method Invocation)与方法的执行(Method Execution)进行解耦(Decoupling)来提高并发性。若以任务的概念来说,Active Object模式的核心则是它允许任务的提交(相当于对异步方法的调用)和任务的执行(相当于异步方法的真正执行)分离。这有点类似于System.gc()这个方法:客户端代码调用完gc()后,一个进行垃圾回收的任务被提交,但此时JVM并不一定进行了垃圾回收,而可能是在gc()方法调用返回后的某段时间才开始执行任务-回收垃圾。我们知道,System.gc()的调用方代码是运行在自己的线程上(通常是main线程派生的子线程),而JVM的垃圾回收这个动作则由专门的工作者线程(垃圾回收线程)来执行。换而言之,System.gc()这个方法所代表的动作(其所定义的功能)的调用方法和执行方法是运行在不同的线程中的,从而提高了并发性。

        当ActiveObject 模式对外暴露的异步方法被调用时,与该方法调用相关的上下文信息,包括被调用的异步方法名(或其代表的操作)、客户端代码所传递的参数等,会被封装成一个对象。该对象被称为方法请求(Method Request)。方法请求对象会被存入Active Object模式所维护的缓冲区(Activation Queue)中,并由专门的工作者线程负责根据其包含的上下文

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值