博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
设计模式之命令模式
阅读量:4034 次
发布时间:2019-05-24

本文共 3020 字,大约阅读时间需要 10 分钟。

古时候有一天,皇帝大发善心,要大赦天下而且还要减轻赋税,于是大臣们根据皇帝不同的旨意传达不同的指令,不管是什么指令,最终都是由老百姓来执行。这就是命令模式。

一、认识命令模式

1、概念

将客户的请求传入一个对象,请求不同传入的对象也不同。因此可实现二者之间的松耦合,以便适应变化。分离变化与不变的因素。

意思是什么呢?假如皇帝想要大赦天下,那么大臣们就可以根据皇帝的意思,传达大赦天下的指令。皇帝有想要减轻赋税,大臣们可以根据皇帝旨意,传达减轻赋税的指令,皇帝的请求不同,那么大臣们传达的指令也不同。现在应该明白了吧。

2、类图

在这里插入图片描述

从上面这张类图我们不难发现,皇帝的最终意思就是要让老百姓去执行,但是自己又不能亲力亲为,于是只把意思跟大臣们一说,大臣们颁布传达具体的指令,最终让老百姓去执行。

这里有五个角色,我们来分析一下:

(1)抽象命令接口Command(圣旨):声明执行的方法。

(2)具体命令对象ConcreteCommand(具体圣旨):具体的命令。

(3)接受者对象Receiver(老百姓):接受者对象,真正执行命令的对象。

(4)传递命令对象Invoker(大臣):持有命令对象,要求Receiver执行请求。

(5)客户端对象Client(皇帝):创建具体命令,设置命令对象的接受者。

3、命令模式与代理模式的区别

这个模式乍一看有点像代理模式,怎么看都是大臣是一个代理,其实不是,在这里我们提前说明一下,免得你稀里糊涂看完了一头雾水,下面进行一个对比分析。

(1)在代理(委托)模式中,调用者就是委托者,执行者就是被委托者,委托者和被委托者接口定义是相同的。命令模式不同,调用者不关注执行者的接口定义是否和它一致。

我们还是拿皇帝与大臣的关系举例子,代理模式中,要求皇帝和大臣们接口定义一样,也就是执行一样的操作。但是命令模式不同,皇帝和大臣的接口定义可以不一致,皇帝可以有自己其他的想法。

(2)在调用时机上,代理模式的具体执行是只能在特定的调用者内部执行(接口相同);命令模式的具体执行可以在任何调用者内部执行(接口不相同也可以)。

意思是什么呢?在代理模式中大臣们只执行一个皇帝(同一个人,谁当皇帝都只听朱元璋的)的命令,命令模式不一样,大臣们可以执行好几个皇帝的命令,也就是说不管谁当皇帝,都只听在任皇帝的。

现在你能分清了吧,那我们就具体来看一下命令模式如何实现的。

二、代码实现命令模式

第一步:创建接受者(老百姓)

public class People {
//执行赦免命令 public void exePardonCommand() {
System.out.println("老百姓执行赦免命令"); } //执行减税命令 public void exeReduceTaxCommand() {
System.out.println("老百姓执行减税命令"); }}

第二步:抽象命令接口Command(圣旨)

public interface Command {
public void execute();}

第三步:具体命令对象ConcreteCommand(具体圣旨)

首先是大赦天下

//大赦天下public class PardonCommand implements Command{
People people; public PardonCommand(People people) {
this.people = people; } //大臣们也不会执行,真正执行的是百姓 @Override public void execute() {
people.exePardonCommand(); }}

然后是减轻赋税

public class ReduceTaxCommand implements Command{
People people; public ReduceTaxCommand(People people) {
this.people = people; } //大臣们也不会执行,真正执行的是百姓 @Override public void execute() {
people.exeReduceTaxCommand(); }}

第四步:传递命令对象Invoker(大臣)

public class Minister {
//大臣们把皇帝的旨意都创建好了 private Command pardomCommand,reduceTaxCommand; public Minister(Command pardomCommand, Command reduceTaxCommand) {
this.pardomCommand = pardomCommand; this.reduceTaxCommand = reduceTaxCommand; } //然后大臣让老百姓去真正执行就OK了 public void pardon() {
pardomCommand.execute(); } public void reduceTax() {
reduceTaxCommand.execute(); }}

第五步:客户端对象Client(皇帝)模拟整个过程

public class Emperor {
public static void main(String[] args) {
//老百姓 People people=new People(); //皇帝的指令:大赦天下和减轻赋税 Command pardonCommand=new PardonCommand(people); Command reduceTaxCommand=new ReduceTaxCommand(people); //把命令传达给大臣 Minister minister=new Minister(pardonCommand, reduceTaxCommand); //大臣们去让老百姓去执行 minister.pardon(); minister.reduceTax(); }}//output://老百姓执行赦免命令//老百姓执行减税命令

三、分析命令模式

1、使用场景

命令模式适用于“请求-响应”模式的功能,把用户的请求封装成具体的命令对象,用户请求什么,我们就调用什么命令,用户无需知道命令执行逻辑是什么。

2、优缺点

优点:将用户的请求和请求的实现实现解耦,用户有了新需求,只需要增加一个需求实现对象即可。

缺点:请求比较多的时候,会使得整个类变得庞大。

OK,这就是命令模式,如有问题还请批评指正。

求封装成具体的命令对象,用户请求什么,我们就调用什么命令,用户无需知道命令执行逻辑是什么。

2、优缺点

优点:将用户的请求和请求的实现实现解耦,用户有了新需求,只需要增加一个需求实现对象即可。

缺点:请求比较多的时候,会使得整个类变得庞大。

OK,这就是命令模式,如有问题还请批评指正。

欢迎关注微信公众号:java的架构师技术栈,回复关键字可获取从小白到架构师的学习路线和视频书籍资源。感谢关注

在这里插入图片描述

转载地址:http://zmbdi.baihongyu.com/

你可能感兴趣的文章
Best Time to Buy and Sell Stock
查看>>
Binary Tree Zigzag Level Order Traversal
查看>>
ZigZag Conversion
查看>>
[leetcode]:Two Sum
查看>>
leetcode: 3Sum
查看>>
leetcode:3sum closet
查看>>
【剑指offer】面试题37:两个链表的第一个公共结点
查看>>
【剑指offer】面试题39:二叉树的深度
查看>>
【剑指offer】面试题28的习题:正方体,八皇后
查看>>
【剑指offer】面试题42:单词翻转顺序&左右旋转字符串
查看>>
【剑指offer】面试题43:n个骰子的点数
查看>>
堆排序及其相关操作
查看>>
【剑指offer】 堆排序查找最小的K个数
查看>>
【剑指offer】q50:树中结点的最近祖先
查看>>
二叉树的非递归遍历
查看>>
【leetcode】Reorder List (python)
查看>>
【leetcode】Linked List Cycle (python)
查看>>
【leetcode】Linked List Cycle (python)
查看>>
【leetcode】Word Break(python)
查看>>
【剑指offer】面试题26:复杂链表的复制
查看>>