Java设计模式之命令模式

简介:

命令模式定义:将“请求”封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象。命令模式也支持撤销的操作。

通常一个命令对象就是要执行的一个命令操作,实现了共同的接口,一个命令对象通过在特定的接受者上绑定一组动作来封装一个请求。一般命令对象将所要操作的动作和接受者绑定在里面,通过提供给外部一个execute()方法来触发所需要的操作。
命令模式实现了“命令的调用者”和“命令的接受者”之间的解耦,由于命令对象里面已经绑定了所要操作的接受者以及动作,而调用者只管负责调用相应的命令对象来完成命令所包含的动作,调用者根本不知道它所操作的是哪一个接受者,只知道它要做的是何种操作而已。
其实命令模式如同其他设计模式一样——通过将你的的请求和你的处理之间,加上了一个中间人的角色,来达到分离耦合的目的。通过对中间人角色的特殊设计来形成不同的模式。当然命令模式就是一种特殊设计的结果。
它的类图如下:
命令模式类图
通常它的组成包括如下:
1) 命令角色(Command):声明执行操作的接口。由接口或者抽象类来实现。
2) 具体命令角色(Concrete Command):将一个接收者对象绑定于一个动作,调用接收者相应的操作,以实现命令角色声明的执行操作的接口。
3) 客户角色(Client):创建一个具体命令对象(并可以设定它的接收者)。
4) 调用者角色(Invoker):调用命令对象执行这个请求。
5) 接收者角色(Receiver):知道如何实施与执行一个请求相关的操作。任何类都可能作为一个接收者。
一般来说具体命令角色仅仅包含着一种命令,如果想要一个命令包含多种命令那么就可以利用宏命令,在一个具体命令角色中提前设置好各种具体命令角色来处理。
命令模式一般具有撤销操作,一般就是在调用者里面做好预处理,在每一个具体命令角色设置好撤销操作的执行动作
命令模式的优点:
1) 命令模式将调用操作的请求对象与执行该操作的接收对象解耦。
2) 具体命令角色可以被不同的请求者角色重用。
3) 可将多个命令装配成一个复合命令,即宏命令。
4) 增加新的具体命令角色很容易,因为这无需改变已有的类。
命令模式的应用场景:
1) 需要抽象出待执行的动作,然后以参数的形式提供出来——类似于过程设计中的回调机制。而命令模式正是回调机制的一个面向对象的替代品。
2) 在不同的时刻指定、排列和执行请求。
3) 需要支持取消操作。
4) 支持修改日志功能。这样当系统崩溃时,这些修改可以被重做一遍。
5) 需要支持事务操作。
命令模式的要点:
1)在被解耦的两者之间即接受者和调用者通过命令对象来沟通的。
2)调用者通过调用命令对象的execute()发出请求,这就会促使接受者开始执行命令的动作。
举例说明:
一个控制器,可以控制许多个设备,通过向设备发出各种命令来执行。
命令角色接口:
package com.whut.command;
//各种命令的基类
public interface Command {
void execute();
void undo();
}
具体命令角色:
package com.whut.command;
public class LightOffCommand  implements Command {
Light light;
public LightOffCommand(Light light)
{
this.light=light;
}

@Override
public void execute() {
// TODO Auto-generated method stub
light.off();
}

@Override
public void undo() {
// TODO Auto-generated method stub
light.on();
}
}
调用者角色:
package com.whut.command;

public class RemoteControl {

private Command[] onCommands;
private Command[] offCommands;
private Command undoCommand;

public RemoteControl()
{
onCommands= new Command[7];
offCommands= new Command[7];

undoCommand= new NoCommand();
for( int i=0;i<7;i++)
{
onCommands[i]= new NoCommand();
offCommands[i]= new NoCommand();
}
}

public void setCommand( int slot,Command onCommand,Command offCommand)
{
onCommands[slot]=onCommand;
offCommands[slot]=offCommand;
}

public void onButtonWasPressed( int slot)
{
onCommands[slot].execute();
undoCommand=onCommands[slot];
}

public void offButtonWasPressed( int slot)
{
offCommands[slot].execute();
undoCommand=offCommands[slot];
}

public void undoButtonWasPressed()
{
undoCommand.undo();
}

@Override
public String toString()
{
StringBuffer stringBuff= new StringBuffer();
stringBuff.append( "\n------Remote Control-------------\n");
for( int i=0;i<7;i++)
{
stringBuff.append( "[slot "+i+ " ]"+onCommands[i].getClass().getName()
+ " "+offCommands[i].getClass().getName()+ "\n");
}
return stringBuff.toString();
}
}
接受者角色:
package com.whut.command;
//各种接受者
public class Light {

private String lightType;

public Light(String light)
{
this.lightType=light;
}
public void on()
{
System.out.println( "The "+lightType+ " is on...");
}

public void off()
{
System.out.println( "The "+lightType+ " is off...");
}
}
客户角色:
package com.whut.command;
public class RemoteLoader {
public static void main(String[] args)
{
RemoteControl remote= new RemoteControl();

Light livingRoomLight= new Light( "Living Room");
LightOnCommand livingRoomOn= new LightOnCommand(livingRoomLight);
LightOffCommand livingRoomOff= new LightOffCommand(livingRoomLight);
remote.setCommand(0, livingRoomOn, livingRoomOff);

remote.onButtonWasPressed(0);
remote.offButtonWasPressed(0);
System.out.println(remote);
remote.undoButtonWasPressed();
remote.offButtonWasPressed(0);
remote.onButtonWasPressed(0);
System.out.println(remote);
}
}


本文转自 zhao_xiao_long 51CTO博客,原文链接:http://blog.51cto.com/computerdragon/1156583

相关文章
|
10天前
|
设计模式 Java
Java中的设计模式及其应用场景解析
Java中的设计模式及其应用场景解析
|
7天前
|
设计模式 测试技术 Python
《手把手教你》系列基础篇(九十二)-java+ selenium自动化测试-框架设计基础-POM设计模式简介(详解教程)
【7月更文挑战第10天】Page Object Model (POM)是Selenium自动化测试中的设计模式,用于提高代码的可读性和维护性。POM将每个页面表示为一个类,封装元素定位和交互操作,使得测试脚本与页面元素分离。当页面元素改变时,只需更新对应页面类,减少了脚本的重复工作和维护复杂度,有利于团队协作。POM通过创建页面对象,管理页面元素集合,将业务逻辑与元素定位解耦合,增强了代码的复用性。示例展示了不使用POM时,脚本直接混杂了元素定位和业务逻辑,而POM则能解决这一问题。
25 6
|
5天前
|
设计模式 Java 测试技术
《手把手教你》系列基础篇(九十四)-java+ selenium自动化测试-框架设计基础-POM设计模式实现-下篇(详解教程)
【7月更文挑战第12天】在本文中,作者宏哥介绍了如何在不使用PageFactory的情况下,用Java和Selenium实现Page Object Model (POM)。文章通过一个百度首页登录的实战例子来说明。首先,创建了一个名为`BaiduHomePage1`的页面对象类,其中包含了页面元素的定位和相关操作方法。接着,创建了测试类`TestWithPOM1`,在测试类中初始化WebDriver,设置驱动路径,最大化窗口,并调用页面对象类的方法进行登录操作。这样,测试脚本保持简洁,遵循了POM模式的高可读性和可维护性原则。
13 2
|
8天前
|
设计模式 安全 Java
Java面试题:设计模式如单例模式、工厂模式、观察者模式等在多线程环境下线程安全问题,Java内存模型定义了线程如何与内存交互,包括原子性、可见性、有序性,并发框架提供了更高层次的并发任务处理能力
Java面试题:设计模式如单例模式、工厂模式、观察者模式等在多线程环境下线程安全问题,Java内存模型定义了线程如何与内存交互,包括原子性、可见性、有序性,并发框架提供了更高层次的并发任务处理能力
24 1
|
9天前
|
设计模式 Java 数据库连接
Java中的设计模式在实际项目中的应用
Java中的设计模式在实际项目中的应用
|
18天前
|
设计模式 Java
设计模式在Java项目中的实际应用
设计模式在Java项目中的实际应用
|
16天前
|
设计模式 消息中间件 负载均衡
实现可扩展和可靠的分布式系统的Java设计模式
实现可扩展和可靠的分布式系统的Java设计模式
|
17天前
|
设计模式 JavaScript API
js设计模式【详解】—— 命令模式
js设计模式【详解】—— 命令模式
21 6
|
18天前
|
设计模式 缓存 算法
编写高效的Java工具类:实用技巧与设计模式
编写高效的Java工具类:实用技巧与设计模式
|
15天前
|
设计模式 Java 数据安全/隐私保护
Java中的设计模式:从入门到精通
Java中的设计模式:从入门到精通

热门文章

最新文章