三分钟理解“命令模式”——设计模式轻松掌握

什么是命令模式?

假设现在有一个请求处理类(低层类/第三方类),如果客户端拿到这个类之后直接调用它,那么客户端和这个请求处理类之间的藕合度过高。

这时候我们在客户端的请求发送类和请求处理类之间增加一个Invoker类,再将请求发送类发送的所有请求封装成对象,然后让Invoker类去管理这些请求对象,并决定这些请求是否允许执行、何时执行、按什么顺序执行。

由于在请求发送类和请求处理类之间增加了请求转发者,因此这两个类之间的藕合度就大大降低。

命令模式的类图

1.Invoker类用于管理客户端想要发送的请求Command;

Invoker中有一个List<Command>,用于存放客户端发来的还没有被执行的请求;

客户端通过Invoker类中的add、delete函数,向Invoker发送或删除请求;

客户端通过Invoker类的executeCommand()函数,一次性执行Invoker中尚未被执行的请求。

2.当客户端执行Invoker的executeCommand()函数时,该函数实际调用了当前Command对象肚子中的executeCommand()函数。

Command类中含有请求处理者Receiver的对象,客户端通过Command对象中的setReceiver(Receiver)函数来设置;

当客户端调用Invoker的executeCommand()时,该函数调用了当前Command对象的executeCommand()函数,该函数再调用Command肚子中那个Receiver对象的具体处理函数。

客户端代码:

main(){
	//创建Receiver对象
	Receiver receiver = new Receiver();

	//创建Command对象,并往Command肚子里设置该命令所要执行的处理类的对象
	Command commandA = new ConcreteCommandA();
	commandA.setReceiver(receiver);

	Command commandB = new ConcreteCommandB();
	commandB.setReceiver(receiver);

	//创建Invoker对象,并往它肚子里添加需要处理的命令
	Invoker invoker = new Invoker();
	invoker.add(commandA);
	invoker.add(commandB);

	//执行Invoker肚子里的所有命令
	invoker.executeCommand();
}

命令模式的优点

1.命令模式将请求发送者和请求处理者分离开,从而降低了这两个类之间的藕合;

2.通过在请求发送者和请求处理者之间增加转发类的方式,从而客户端发出的请求可以在被处理之前都存放在Invoker类的容器中,请求在被执行前就有了一个缓冲,能起到以下作用:

a)Invoker能够对客户端发出的请求进行排序;

b)Invoker能够决定是否需要驳回请求;

c)客户端可以在请求被执行前选择撤销某个请求;

d)在需要的情况下,客户端的请求可以被记录成日志;

3.增加新的命令时只需增加新的命令子类即可。

是否需要在程序设计的时候去猜测未来可能发生的事情?

不需要!敏捷开发原则告诉我们:不要为代码添加基于猜测的功能!

如果不清楚一个系统是否需要命令模式,就不要着急着去实现它;在需要的时候通过重构代码实现这个模式。

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

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏开发技术

spring集成mybatis实现mysql读写分离

       在网站的用户达到一定规模后,数据库因为负载压力过高而成为网站的瓶颈。幸运的是目前大部分的主流数据库都提供主从热备功能,通过配置两台数据库主从关系,...

691
来自专栏阿杜的世界

Spring Boot应用的测试——Mockito

Spring Boot可以和大部分流行的测试框架协同工作:通过Spring JUnit创建单元测试;生成测试数据初始化数据库用于测试;Spring Boot可以...

801
来自专栏小灰灰

Java实现几种简单的重试机制

背景 当业务执行失败之后,进行重试是一个非常常见的场景,那么如何在业务代码中优雅的实现重试机制呢? 设计 我们的目标是实现一个优雅的重试机制,那么先来看下怎么...

8398
来自专栏Kevin-ZhangCG

[ SSH框架 ] Hibernate框架学习之一

 CRM(Customer Realationship Management)客户关系管理,是利用相应的技术信息以及互联网技术来协调企业与顾客间在销售、营销和...

3317
来自专栏Java3y

WebService就是这么简单

WebService介绍 首先我们来谈一下为什么需要学习webService这样的一个技术吧…. 问题一 如果我们的网站需要提供一个天气预报这样一个需求的话,那...

1.8K14
来自专栏大魏分享(微信公众号:david-share)

如何使用模拟框架测试微服务? | 微服务系列第八篇

作为开发人员尝试创建集成测试时,会遇到许多复杂问题。出现的两个最常见的问题包括与:

1912
来自专栏开发 & 算法杂谈

Zookeeper C API学习总结

客户端使用C语言开发,zookeeper提供了两个库,zookeeper_st(单线程库)以及zookeeper_mt(多线程库)。

3745
来自专栏IT技术精选文摘

从Java视角理解系统结构(三)伪共享

从我的前一篇博文中, 我们知道了CPU缓存及缓存行的概念, 同时用一个例子说明了编写单线程Java代码时应该注意的问题. 下面我们讨论更为复杂, 而且更符合现实...

1897
来自专栏无题

Spring Boot核心原理-自动配置

为什么spring boot能够如此简单的让我们迅速上手。 之前在公司内部推行spring boot时,有同事跟我提到过,感觉换到spring boot这个框...

3734
来自专栏SpringBoot 核心技术

第三十五章:SpringBoot与单元测试的小秘密

2105

扫码关注云+社区