命令模式 - 行为模式

个人理解:    

模式类型:

    Command  命令模式 - 行为模式 (命令模式又称为动作(Action)模式或事务(Transaction)模式。)
    
意图:
    encapsulate a request in an object
    allows the parameterization of clients with different requests
    allows saving the requests in a queue
    将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或者记录请求日志,以及支持可撤消的操作。命令模式又称为动作(Action)模式或事务(Transaction)模式。

    
概述:
    命令模式的本质是: 封装请求

    命令模式还有一个常见的用法就是执行事务操作。这就是为什么命令模式还叫做事务模式的原因吧。
    它可以在请求被传递到接收者角色之前,检验请求的正确性,甚至可以检查和数据库中数据的一致性,而且可以结合组合模式的结构,来一次执行多个命令。

    
    有时必须向某对象提交请求,但并不知道关于被请求的操作或请求的接受者的任何信息。提交一个请求的对象仅需直到如何提交它,而不需要知道该请求将会如何被执行。模式通过将请求本身变成一个对象来使工具箱对象可向未指定的应用对象提出请求。这个对象可被存储并像其他的对象一样被传递。模式的关键是一个抽象的Command类,它定义了一个执行操作的接口,最简单的入execute,具体的command子类将接收者作为其中一个实例变量,用接收者的方法实现execute操作。接收者有指向该请求所需的具体信息。
    
角色:
    命令(Command)角色:定义命令的接口,声明执行的方法。
    具体命令(ConcreteCommand)角色:命令接口实现对象,是“虚”的实现,通常它会持有命令的接收者,通过调用接收者相应的功能方法来执行当前命令所要完成的操作。
    接收者(Receiver)角色:真正执行命令的对象。任何类都可以成为一个接收者,只要它能够实现命令要求实现的相应功能即可。
    请求者(Invoker)角色:要求命令对象执行相关请求的对象,通常会持有命令对象,可以是多个命令对象。这是客户端真正触发命令并要求命令执行相应操作的入口点。
    客户端(Client)角色:创建具体的命令对象,并设置命令对象的接收者。注意,这里的客户端并不是我们通常所指的客户端,而是指组装命令和接收者的地方,把这个Client称为装配者或者意义会更明了,真正使用命令的客户端是从Invoker来触发执行的,而不是从这个Client端命令的调用。


结构图:


模式的应用场景:
1) 需要抽象出待执行的动作,然后以参数的形式提供出来——类似于过程设计中的回调机制。而命令模式正是回调机制的一个面向对象的替代品。
2) 在不同的时刻指定、排列和执行请求。一个命令对象可以有与初始请求无关的生存期。
3) 需要支持取消操作。
4) 支持修改日志功能。这样当系统崩溃时,这些修改可以被重做一遍。
5) 需要支持事务操作。
6) 使用命令模式作为"CallBack"在面向对象系统中的替代。"CallBack"讲的便是先将一个函数登记上,然后在以后调用此函数。

模式的优缺点:
一、能较容易地建立一个命令队列;
二、在需要的情况下,可以较容易地将命令记入日志;
三、允许接收请求的一方是否拒绝请求;
四、可以容易地实现对请求的撤销和重做,
五、由于加进新的具体命令类不影响其他的类,因此添加一个新命令类不影响其它类;

最关键的优点:命令模式把请求一个操作的对象与知道怎么操行一个操作的对象分开。适用原则:敏捷开发原则告诉我们,不要为代码添加基于猜测的、实际不需要的功能。如果不清楚一个系统是否需要命令模式,一般不要着急去实现它,事实上、在需要的时候通过重构实现这个模式并不困难,只有在真正需要如撤销、恢复等操作功能时,才把原有的代码重构为命令模式才有意义。
    
模式在实际中的应用
命令模式在MVC中的应用:
    Struts中,在模型层都要继承一个Action接口,并实现execute方法,其实这个Action就是命令类。为什么Struts会应用命令模式,是因为Struts的核心控制器ActionServlet只有一个,相当于Invoker,而模型层的类会随着不同的应用有不同的模型类,相当于具体的Command。这样,就需要在ActionServlet和模型层之间解耦,而命令模式正好解决这个问题。
      
代码(其实读UML图要比代码还要一目了然)
例子中,Receiver被封装到了Commond中,然后再由Invoker去调用。
package com.lee.desingerPattener23.command.example1;

public class Client {
	public static void main(String[] args) {
		// 创建接收者
		Receiver receiver = new Receiver();
		// 创建命令对象,设定它的接收者
		Command command = new ConcreteCommand(receiver);
		// 创建Invoker,把命令对象设置进去
		Invoker invoker = new Invoker();
		invoker.setCommand(command);
		invoker.runCommand();
	}
}
//命令的真正实现者
class Receiver {
	public void action() {
		// 真正执行命令操作的功能代码
		System.out.println("真正执行命令操作的功能代码");
	}
}
//命令对象
interface Command {
	public void execute();
}
class ConcreteCommand implements Command {
	private Receiver receiver = null;
	private String state;
	public ConcreteCommand(Receiver receiver) {
			this.receiver = receiver;
	}
	public void execute() {
		receiver.action();
	}
}
//请求者
class Invoker {
	private Command command = null;
	public void setCommand(Command command) {
		this.command = command;
	}
	public void runCommand() {
		command.execute();
	}
}


所有模式:
     创建型模式,共五种:工厂方法模式、抽象工厂模式单例模式建造者模式原型模式
结构型模式,共七种:适配器模式装饰器模式代理模式外观模式桥接模式组合模式享元模式
    行为型模式,共十一种:策略模式模板方法模式观察者模式迭代子模式责任链模式命令模式备忘录模式状态模式访问者模式中介者模式解释器模式
    补充模式:空对象模式

参考/转自:

http://www.cnblogs.com/xudong-bupt/p/3617860.html
http://blog.csdn.net/xlf13872135090/article/details/22158481
http://www.oodesign.com/command-pattern.html


转载请注明:    http://blog.csdn.net/paincupid/article/details/46947957

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值