设计模式系列之命令模式

命令模式

1 使用场景

1. 命令的发送者和命令执行者有不同的生命周期。命令发送了并不是立即执行。

2. 命令需要进行各种管理逻辑。

3. 需要支持撤消\重做操作(撤销命令)。

2 角色

2.1 client

1、创建具体的命令

2、设置命令的接受者

2.2 Command

1 定义命令的统一接口

2 command为所有命令声明了一个借口,调用命令对象的excute方法,就可以让接受者进行相关的操作

3 这个接口也具备撤销的方法

2.3 ConcreteCommand

1 Command接口的实现者,用来执行具体的命令,某些情况下可以直接用来充当Receiver。

2 具体命令会调用接受者的动作,以满足请求

2.4 invoker

1 命令的实际执行者

2 这个调用者持有一系列命令对象,并在某个时间调用命令对象的excute方法,将请求付诸实行。

2.5 Receiver

1 命令的请求者,是命令模式中最重要的角色。这个角色用来对各个命令进行控制。

2 命令对象通过在特定接受者上绑定一组动作来封装一个请求

3 接受者有多个

4 接受者经常通过参数化对象来绑定到具体命令对象中

5 接受者知道如何进行必要的工作,实现这个请求,任何类都可以当接受者

6 一般情况下,一个具体命令对应一个具体的接受者

3 例子

3.1 客户向服务员点餐-服务员将菜单交给厨师,厨师烹饪各种食物

3.2 使用命令模式的一般步骤

1 第一步:初始化所有的接受者

2 第二步:创建所有的命令对象

3 第三步:调用者加载命令

4 第四步:在适当的时候让调用者执行命令

3.3 demo

package limanman;

import java.util.ArrayList;
import java.util.List;

public class CommandTest {
	public static void main(String[] args) {
		Client.run();
	}
}

class Client {
	public static  void run() {

		/**
		 * 第一步:初始化所有的接受者
		 */
		Receiver1 receiver1 = new Receiver1();
		Receiver2 receiver2 = new Receiver2();

		/**
		 * 第二步:创建所有的命令对象
		 */
		Command command1 = new ConcreateCmonmand1(receiver1);
		Command command2 = new ConcreateCmonmand2(receiver2);

		/**
		 * 第三步:调用者加载命令
		 */
		Invoker invoker = new Invoker();
		invoker.setCommand(command1);
		invoker.setCommand(command2);

		/**
		 * 第四步:在适当的时候让调用者执行命令
		 */
		invoker.callRecever(0);
		invoker.callRecever(1);

	}
}

/**
 * 接受者1,一个具体命令对应一个具体接收者
 *
 * @author limanman
 * @date 2015年10月12日
 */
class Receiver1 {

	public void action() {
		System.out.println("接收者1执行具体的操作");
	}

}

/**
 * 接受者2,一个具体命令对应一个具体接收者
 *
 * @author limanman
 * @date 2015年10月12日
 */
class Receiver2 {

	public void action() {
		System.out.println("接收者2执行具体的操作");
	}

}

/**
 * 命令角色
 *
 * @author limanman
 * @date 2015年10月12日
 */
interface Command {
	public void excute();
}

/**
 * 角色: 具体命令
 *
 * @author limanman
 * @date 2015年10月12日
 */
class ConcreateCmonmand1 implements Command {
	Receiver1 receiver1;

	public ConcreateCmonmand1(Receiver1 receiver1) {
		this.receiver1 = receiver1;
	}

	@Override
	public void excute() {
		System.out.println("执行命令1");
		receiver1.action();

	}

}

class ConcreateCmonmand2 implements Command {
	Receiver2 receiver2;

	public ConcreateCmonmand2(Receiver2 receiver2) {
		this.receiver2 = receiver2;
	}

	@Override
	public void excute() {
		System.out.println("执行命令2");
		receiver2.action();

	}
}

/**
 * 角色:invoker
 *
 * @author limanman
 * @date 2015年10月12日
 */
class Invoker {
	List<Command> commands = new ArrayList<Command>();

	/**
	 * 设置命令
	 *
	 * @param command
	 * @date 2015年10月12日
	 * @author 佚名
	 */
	public void setCommand(Command command) {
		commands.add(command);
	}

	/**
	 * 调用者持有一系列命令对象,并在某个时间点调用对象的excute方法,将请求付诸实行
	 *
	 * @param slot
	 * @date 2015年10月12日
	 * @author 佚名
	 */
	public void callRecever(int slot) {
		commands.get(slot).excute();
	}

}

输出:

执行命令1
接受者1执行具体的操作
执行命令2
接受者2执行具体的操作

4 要点

1 命令模式是通过命令发送者和命令执行者的解耦来完成对命令的具体控制的。

2 命令模式是对功能方法的抽象,并不是对对象的抽象。

3 命令模式是将功能提升到对象来操作,以便对多个功能进行一系列的处理以及封装。

5 设计原则

对修改封闭,对扩展开放

6 核心

1 参数化对象,对象中包含请求和具体的操作

2 请求者创建命令和接受者,接受者执行命令和撤销命令

7 定义

"请求"封装成对象,以便使用不同的请求,队列或者日志来参数化其他对象,命令模式也支持可撤销的操作

8 好处

1.更方便的对命令进行扩展

2.对多个命令的统一控制

3.支持撤销操作

9 问题

9.1 命令模式的设计如何支持请求者和请求接受者之间的解耦

1、invoker只是包含了抽象的命令(interface)

2、具体的命令和接受者跟invoker没有直接的关联

时间: 2024-11-13 09:23:37

设计模式系列之命令模式的相关文章

Java设计模式系列之命令模式

命令模式(Command)的定义 将一个请求封装为一个对象,从而可用不同的请求对客户进行参数化:对请求排队或记录日志,以及支持可撤销的操作,将”发出请求的对象”和”接收与执行这些请求的对象”分隔开来. 命令模式(Command)的适用性 1.抽象出待执行的动作以参数化某对象. 2.在不同的时刻指定.排列和执行请求. 3.支持取消操作. 4.支持修改日志,这样当系统崩溃时,这样修改可以被重做一遍. 5.用构建在原语操作上的高层操作构造一个系统. 命令模式(Command)的应用效果:1)comma

Java设计模式菜鸟系列(七)命令模式建模与实现

转载请注明出处:http://blog.csdn.net/lhy_ycu/article/details/39804057 命令模式(Command):将"请求"(命令/口令)封装成一个对象,以便使用不同的请求.队列或者日志来参数化其对象.命令模式也支持撤销操作.命令模式的目的就是达到命令的发出者和执行者之间解耦,实现请求和执行分开. 一.uml建模 二.代码实现: /** * 示例:以咱去餐馆吃饭为例,分为3步 * * 1.和小二说,来个宫保鸡丁 --> 顾客发出口令 * *

[js高手之路]设计模式系列课程-组合模式+寄生组合继承实战新闻列表

所谓组合模式,就是把一堆结构分解出来,组成在一起,现实中很多这样的例子,如: 1.肯德基套餐就是一种组合模式, 比如鸡腿堡套餐,一般是是由一个鸡腿堡,一包薯条,一杯可乐等组成的 2.组装的台式机同理,由主板,电源,内存条,显卡, 机箱,显示器,外设等组成的 把一个成型的产品组成部件,分成一个个独立的部件,这种方式可以做出很多灵活的产品,这就是组合模式的优势 比如:家用台式机电脑,要求配置比较低, 这个时候只需要主板+电源+内存条+机箱+显示器+外设就可以了,不需要配置独立显卡 鸡腿堡+鸡翅+紫薯

设计模式-行为型-命令模式(COMMAND)

命令模式是一个结构比较简单的设计模式,gof在书中对它的定义是:"将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化:对请求排队或记录请求日志,以及支持可撤消的操作." 这里有两个要点,第一请求被封装成了一个对象,第二请求可以被持久化(排队或是记录.取消). 我们从第一个要点说起.首先需要注意一点的所有COMMAND的模型都可以抽象出一个Execute概念或是类似概念.如下图(左)一样,这里的请求就是对文档做出paste操作,封装的结果就是通过PasteCommand的一

Android设计模式系列--工厂方法模式

工厂方法模式,往往是设计模式初学者入门的模式,的确,有人称之为最为典型最具启发效果的模式.android中用到了太多的工厂类,其中有用工厂方法模式的,当然也有很多工厂并不是使用工厂方法模式的,只是工具管理类.今天以ThreadFactory举例说明一下简单工厂模式和工厂方法模式. 工厂方法模式,Factory Method,简单的方式,不简单的应用. 1.意图定义一个用于创建对象的接口,让子类决定实例化哪个类.工厂方式模式使一个类的实例化延迟到其子类.热门词汇:虚构造器 延迟 创建对象 子类 2

从王者荣耀看设计模式(九.命令模式)

从王者荣耀看设计模式(命令模式) 一.简介 王者荣耀是一款团队竞技游戏.良好的团队信息交流在一定程度上能帮助队伍取得胜利.为了保证游戏的流畅性与便捷性,王者荣耀提供了快捷交流机制,在王者小地图旁边有几个快捷聊天按钮(开始撤退,发起进攻,请求结合),玩家可通过点击快捷聊天按钮发出相应命令与队友进行交流 二.命令模式 命令模式(Command Pattern):命令模式是一种高内聚的模式,将"请求"封装成对象,以便使用不同的请求.队列或者日志来参数化其他对象.命令模式也支持可撤销的操作.

设计模式系列 - 行为型模式(下)

行为设计模式是识别对象之间的通信模式,行为模式涉及对象之间的责任分配,或者,将行为封装在对象中并将请求委托给它,也就是对象之间的关系. 涉及:* 状态模式中介模式* 观察者模式备忘录模式迭代器模式命令模式* 策略模式* 模板模式* 访客模式示例责任链模式 观察者模式 根据GoF定义,observer模式定义了对象之间的一对多依赖关系,当一个对象改变状态时,它的所有依赖关系都会被自动通知和更新.它也被称为发布-订阅模式.在观察者模式中,有许多观察者(订阅者对象)正在观察特定的主题(发布者对象).观

Java-马士兵设计模式学习笔记-命令模式

一.概述 命令模式 二.代码 1.Client.java 1 public class Client { 2 3 public void request(Server server){ 4 server.addCommand(new TextCommand()); 5 server.addCommand(new ImageCommand()); 6 server.doSomething(); 7 } 8 } 2.Server.java 1 public class Server { 2 3 pr

设计模式(14)--Command(命令模式)--行为型

作者QQ:1095737364    QQ群:123300273     欢迎加入! 1.模式定义:   命令模式属于对象的行为模式.命令模式又称为行动(Action)模式或交易(Transaction)模式.   命令模式把一个请求或者操作封装到一个对象中.命令模式允许系统使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能. 2.模式特点: 在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个,我们只需在程序