java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Java命令模式CommandPattern

Java设计模式之命令模式CommandPattern详解

作者:chengmaoning

这篇文章主要介绍了Java设计模式之命令模式CommandPattern详解,命令模式是把一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作,需要的朋友可以参考下

概念

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

在软件系统中,“行为请求者”与“行为实现者”通常呈现一种“紧耦合”。但在某些场合,比如要对行为进行“记录、撤销/重做、事务”等处理,这种无法抵御变化的紧耦合是不合适的。在这种情况下,如何将“行为请求者”与“行为实现者”解耦?将一组行为抽象为对象实现二者之间的松耦合。这就是命令模式(Command Pattern)

UML模式结构分析

Command接口

定义命令的接口,声明执行的方法execute()。

ConcreteCommand子类:

命令接口实现对象,不同命令对应不同子类。通常具体命令类会持有接受者引用,并调用接收者的功能来完成命令要执行 的操作。

Receiver类

接收者,真正执行命令的对象。任何类都可能成为一个接收者,只要它能够实现命令要求实现的相应功能。

Invoker类:

要求命令对象执行请求,通常会持有命令对象,可以持有很多的命令对象。这个是客户端真正触发命令并要求命令执行相应操作的地方,也就是说相当于使用命令对象的入口。

Client类:

创建具体的命令对象,并且设置命令对象的接收者。注意这个不是我们常规意义上的客户端,而是在组装命令对象和接收者,或许,把这个Client称为装配者会更好理解,因为真正使用命令的客户端是从Invoker来触发执行。

模式协作

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

实例解析

电视机是请求的接收者(Receiver),遥控器是请求的发送者(Invoker),遥控器上有一些按钮,不同的按钮对应电视机的不同操作(ConcreteCommand)。抽象命令角色由一个命令接口(Command)来扮演,有三个具体的命令类实现了抽象命令接口,这三个具体命令类分别代表三种操作:打开电视机、关闭电视机和切换频道。显然,电视机遥控器就是一个典型的命令模式应用实例。

接收者Television:

package commandpattern;
 
public class Television {
	private int channel;
 
	public void turnOn() {
		System.out.println("The televison is on.");
	}
 
	public void turnOff() {
		System.out.println("The television is off.");
	}
 
	public void changeChannel(int channel) {
		this.channel = channel;
		System.out.println("Now televison channel is " + channel);
	}
}

命令接口:

package commandpattern;
 
public interface Command {
	public void execute();
}

具体命令——打开电视机CommandOn:

package commandpattern;
 
public class CommandOn implements Command {
 
	private Television television;
 
	public CommandOn(Television television) {
		this.television = television;
	}
 
	@Override
	public void execute() {
		// TODO Auto-generated method stub
		television.turnOn();
	}
 
}

具体命令——切换频道CommandChange:

package commandpattern;
 
public class CommandChange implements Command {
	private Television television;
	private int channel;
 
	public CommandChange(Television television,int channel) {
		this.channel = channel;                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
		this.television = television;
	}
 
	@Override
	public void execute() {
		// TODO Auto-generated method stub
		television.changeChannel(channel);
	}
 
}

具体命令——关闭电视机CommandOff:

package commandpattern;
 
public class CommandOff implements Command {
 
	private Television television;
 
	public CommandOff(Television television) {
		this.television = television;
	}
 
	@Override
	public void execute() {
		// TODO Auto-generated method stub
		television.turnOff();
	}
 
}

命令发起人Invoker,这里就是遥控器Control类,它持有多种具体命令对象:

package commandpattern;
 
public class Control {
	private Command onCommand, offCommand, changeCommand;
 
	public Control(Command on, Command off, Command change) {
		onCommand = on;
		offCommand = off;
		changeCommand = change;
	}
 
	public void turnOn() {
		onCommand.execute();
	}
 
	public void turnOff() {
		offCommand.execute();
	}
 
	public void changeChannel() {
		changeCommand.execute();
	}
}

客户端Client,创建接收者,创建具体命令持有接收者,创建命令发起人持有各种具体命令。

package commandpattern;
 
public class Client {
 
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//命令接收者
		Television television = new Television();
		//命令
		CommandOn on = new CommandOn(television);
		CommandOff off = new CommandOff(television);
		CommandChange change = new CommandChange(television, 4);
		Control control = new Control(on, off, change);
		//执行命令
		control.turnOn();
		control.changeChannel();
		control.turnOff();
	}
 
}

输出:

The televison is on.
Now televison channel is 4
The television is off.

其实命令模式像很多设计模式一样——通过在你的请求和处理之间加上了一个中间人的角色,来达到分离耦合的目的。通过对中间人角色的特殊设计来形成不同的模式。

当然命令模式就是一种特殊设计的结果。

优点:

缺点:

使用命令模式可能会导致某些系统有过多的具体命令类。因为针对每一个命令都需要设计一个具体命令类,因此某些系统可能需要大量具体命令类,这将影响命令模式的使用。

到此这篇关于Java设计模式之命令模式CommandPattern详解的文章就介绍到这了,更多相关Java命令模式CommandPattern内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文