JAVA 设计模式 命令模式

用途

命令模式 (Command)

将一个请求封装为一个对象,从而使你可以用不同的请求对客户进行参数化; 对请求排队或请求日志,以及支持可撤销的操作。

命令模式是一种行为型模式

结构

图-命令模式结构图

Command : 用来声明执行操作的接口。

abstract class Command {
 protected Receiver receiver;
 public Command(Receiver receiver) {
 this.receiver = receiver;
     }
 
 public abstract void Execute();
 }

ConcreteCommand : 将一个接收者对象绑定一个动作,调用接收者相应的操作,以实现Execute。

class ConcreteCommand extends Command {
 public ConcreteCommand(Receiver receiver) {
 super(receiver);
     }
 
     @Override
 public void Execute() {
         receiver.Action();
     }
 }

Invoker : 要求该命令执行这个请求。

class Invoker {
 private Command command;
 
 public Invoker(Command command) {
 this.command = command;
     }
 
 public void ExecuteCommand() {
         command.Execute();
     }
 }

Receiver : 知道如何实施与执行一个与请求相关的操作,任何类都可能作为一个接收者。

class Receiver {
 public void Action() {
         System.out.println("执行请求");
     }
 }

Client : 创建一个具体命令对象并设定它的接受者。

public class CommandPattern {
 public static void main(String[] args) {
         Receiver receiver = new Receiver();
         Command cmd = new ConcreteCommand(receiver);
         Invoker invoker = new Invoker(cmd);
         invoker.ExecuteCommand();
     }
 }

交互

图-命令模式交互图

1、Client 创建一个 ConcreteCommand 对象并指定他的 Receiver 对象。 2、某个 Invoker 对象存储该 ConcreteCommand 对象。 3、该 Invoker 通过调用 Command 对象的 Execute 操作来提交一个请求。若该命令是可撤销的,ConcreteCommand 就在执行 Execute 操作之前存储当前状态以用于取消该命令。 4、ConcreteCommand 对象对调用它的 Receiver 的一些操作以执行该请求。

要点

1、命令模式的本质是对命令进行封装,将发出命令的责任和执行命令的责任分割开。 2、每一个命令都是一个操作:请求的一方发出请求,要求执行一个操作;接收的一方收到请求,并执行操作。 3、命令模式允许请求的一方和接收的一方独立开来,使得请求的一方不必知道接收请求的一方的接口,更不必知道请求是怎么被接收,以及操作是否被执行、何时被执行,以及是怎么被执行的。 4、命令模式使请求本身成为一个对象,这个对象和其他对象一样可以被存储和传递。 5、命令模式的关键在于引入了抽象命令接口,且发送者针对抽象命令接口编程,只有实现了抽象命令接口的具体命令才能与接收者相关联。

推荐

本文属于 JAVA设计模式系列

参考资料

《大话设计模式》《HeadFirst设计模式》

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏coder修行路

go 源码学习之---Tail 源码分析

已经有两个月没有写博客了,也有好几个月没有看go相关的内容了,由于工作原因最近在做java以及大数据相关的内容,导致最近工作较忙,博客停止了更新,正好想捡起之前...

1132
来自专栏海天一树

Python Selenium爬取百度百科旅游景点的基本信息

在与python文件同级的目录下创建scenic_spots_5A_namelist.txt,内容为

912
来自专栏大内老A

ASP.NET MVC集成EntLib实现“自动化”异常处理[实例篇]

个人觉得异常处理对于程序员来说是最为熟悉的同时也是最难掌握的。说它熟悉,因为仅仅就是try/catch/finally而已。说它难以掌握,则是因为很多开发人员却...

19510
来自专栏lzj_learn_note

Volley源码分析学习

2)根据SDK版本来创建HttpStack的实现,如果是2.3以上的,则使用基于HttpUrlConnection实现的HurlStack,反之,则利用Http...

936
来自专栏WindCoder

《Linux内核分析》之操作系统是如何工作的 实验总结

实验阶段,由于学校网速等条件限制,未能在真机上搭建出实验环境。在实验楼中,将代码粘贴进去出现严重的缩进错位,最终未能完成编译新的。本文以分析关键代码为主。

1053
来自专栏大内老A

回调与并发: 通过实例剖析WCF基于ConcurrencyMode.Reentrant模式下的并发控制机制

对于正常的服务调用,从客户端发送到服务端的请求消息最终会被WCF服务运行时分发到相应的封装了服务实例的InstanceContext上。而在回调场景中,我们同样...

1837
来自专栏Janti

基础巩固——长连接 、短连接、心跳机制与断线重连

本文将从长连接和短连接的概念切入,再到长连接与短连接的区别,以及应用场景,引出心跳机制和断线重连,给出代码实现。

1511
来自专栏程序员的碎碎念

JS动态加载以及JavaScript void(0)的爬虫解决方案

对于使用JS动态加载, 或者将下一页地址隐藏为JavaScript void(0)的网站, 如何爬取我们要的信息呢?

1376
来自专栏刘望舒

Android系统启动流程(四)Launcher启动过程与系统启动流程

前言 此前的文章我们学习了init进程、Zygote进程和SyetemServer进程的启动过程,这一篇文章我们就来学习Android系统启动流程的最后一步:L...

2108
来自专栏Bug生活2048

.net core项目实战之基于Restful API+Swagger项目搭建

然后右击你的项目,在属性中,勾选下生成XML文档文件,Swagger会自动解析对应的XML进行匹配。

1141

扫码关注云+社区