您的位置:首页 > 编程语言 > Java开发

Java设计模式 之 命令模式

2015-09-07 17:00 525 查看

1      从属模式分类

行为性模式

2      命令模式意图

命令模式可将动作的请求者和动作的执行者对象中解耦。

该模式将一个行为操作发起者的请求封装到对象中,该请求由另外一个对象执行。

将动作封装成命令对象,这样一来就可以随心所欲的储存、传递、调用。

做多件事,有多种做法。

3      命令模式结构



4      命令模式代码实现

这里假设有一个需要编程实现功能的遥控器,一共有10组开关按钮需要编程来实现不同的控制逻辑。比如说第一组开关可控制客厅的电灯的开关,第二组开关按钮可控制车库门的升起和落下,使用命令模式代码如下:

4.1    ICommon.java

package com.gof.pattern.command;
 
/**
 * 命令接口
 * @author Administrator
 */
 
public
interface
ICommand {
   
    // 执行
    public
void
execute();
   
    // 撤销
    public
void
undo();
   
}

4.2    Light.java

package com.gof.pattern.command;
 
/**
 * 电灯
 * @author Administrator
 */
 
public
class
Light {
   
    private Stringname;
   
    public Light(String name){
       this.name = name;
    }
   
    public
void
on(){
       System.out.println(name +" light is on!");
    }
   
    public
void
off(){
       System.out.println(name +" light is off!");
    }
 
}

 

4.3    LightOnCommand.java

package com.gof.pattern.command;
 
public
class
LightOnCommand
implements
ICommand {
   
    private Lightlight;
   
    public LightOnCommand(Light light){
       this.light = light;
    }
 
    @Override
    public
void
execute() {
       light.on();
    }
 
    @Override
    public
void
undo() {
       light.off();
    }
}

4.4    LightOffCommand.java

package com.gof.pattern.command;
 
/**
 * 关灯
 * @author Administrator
 *
 */
 
public
class
LightOffCommand implements ICommand {
   
    private Lightlight;
   
    public LightOffCommand(Light light){
       this.light = light;
    }
 
    @Override
    public
void
execute() {
       light.off();
    }
 
    @Override
    public
void
undo() {
       light.on();
    }
}

4.5    Stereo.java

package com.gof.pattern.command;
 
/**
 * 音响
 * @author Administrator
 */
 
public
class
Stereo {
   
    private Stringname;
   
    public Stereo(String name){
       this.name = name;
    }
   
    public
void
on(){
       System.out.println(name +" is on!");
    }
   
    public
void
off(){
       System.out.println(name +" is off!");
    }
   
    public
void
setCd(){
       System.out.println(name +" setCd!");
    }
   
    public
void
setDvd(){
       System.out.println(name +" setDvd!");
    }
   
    public
void
setRadio(){
       System.out.println(name +" setRadio!");
    }
 
    public
void
setVolume(int size){
       System.out.println(name +" setVolume is "+ size +"!");
    }
}
 

4.6    StereoOffWithCDCommand.java

package com.gof.pattern.command;
 
/**
 * 关闭音响
 * @author Administrator
 *
 */
 
public
class
StereoOffWithCDCommand implements ICommand {
   
    private Stereostereo;
   
    public StereoOffWithCDCommand(Stereo stereo){
       this.stereo = stereo;
    }
 
    @Override
    public
void
execute() {
       stereo.off();
    }
 
    @Override
    public
void
undo() {
       stereo.setCd();
       stereo.setVolume(11);
       stereo.on();
    }
 
}

4.7    StereoOnWithCDCommand.java

package com.gof.pattern.command;
 
/**
 * 打开音响
 * @author Administrator
 *
 */
 
public
class
StereoOnWithCDCommand implements ICommand {
   
    private Stereostereo;
   
    public StereoOnWithCDCommand(Stereo stereo){
       this.stereo = stereo;
    }
 
    @Override
    public
void
execute() {
       stereo.setCd();
       stereo.setVolume(11);
       stereo.on();
    }
 
    @Override
    public
void
undo() {
       stereo.off();
    }
}
 

4.8    GarageDoor.java

package com.gof.pattern.command;
 
/**
 * 车库实体类
 * @author Administrator
 *
 */
 
public
class
GarageDoor {
   
    private Stringname;
   
    public GarageDoor(String name){
       this.name = name;
    }
   
    public
void
up(){
       System.out.println(name +" is up!");
    }
   
    public
void
down(){
       System.out.println(name +" is down!");
    }
 
}
 

4.9    GarageDoorUpCommand.java

package com.gof.pattern.command;
 
/**
 * 车库门升起
 * @author Administrator
 */
 
public
class
GarageDoorUpCommand implements ICommand {
   
    private GarageDoorgarageDoor;
   
    public GarageDoorUpCommand(GarageDoor garageDoor){
       this.garageDoor = garageDoor;
    }
 
    @Override
    public
void
execute() {
       garageDoor.up();
    }
 
    @Override
    public
void
undo() {
       garageDoor.down();
    }
 
}
 

4.10       GarageDoorDownCommand.java

package com.gof.pattern.command;
 
/**
 * 车库们落下
 * @author Administrator
 */
 
public
class
GarageDoorDownCommand implements ICommand {
   
    private GarageDoorgarageDoor;
   
    public GarageDoorDownCommand(GarageDoor garageDoor){
       this.garageDoor = garageDoor;
    }
 
    @Override
    public
void
execute() {
       garageDoor.down();
    }
 
    @Override
    public
void
undo() {
       garageDoor.up();
    }
 
}
 

4.11       NoCommand.java

package com.gof.pattern.command;
 
/**
 * 空命令
 * @author Administrator
 *
 */
 
public
class
NoCommand implements ICommand {
 
    @Override
    public
void
execute() {}
 
    @Override
    public
void
undo() {}
 
}

4.12       RemoteControl.java

package com.gof.pattern.command;
 
/**
 * 遥控器
 * @author Administrator
 */
 
public
class
RemoteControl {
   
    private ICommand[]onCommands;
   
    private ICommand[]offCommands;
   
    private ICommandundoCommand;
   
    // 初始化遥控器按钮功能
    public RemoteControl(){
       onCommands = new ICommand[7];
       offCommands = new ICommand[7];
       ICommand noCommand = new NoCommand();
       for(int i=0; i<7; i++){
           onCommands[i] = noCommand;
           offCommands[i] = noCommand;
       }
       undoCommand = noCommand;
    }
   
    public
void
setCommand(int slot, ICommand onCommand, ICommand offCommand){
       onCommands[slot] = onCommand;
       undoCommand.undo();
       offCommands[slot] = offCommand;
    }
   
    // 按某个位置,on按钮
    public
void
onButtonWasPushed(int solt){
       onCommands[solt].execute();
       undoCommand =
onCommands[solt];
    }
   
    // 按某个位置,off按钮
    public
void
offButtonWasPushed(int solt){
       offCommands[solt].execute();
       undoCommand =
offCommands[solt];
    }
   
    // 按undo按钮
    public
void
undoButtonWasPushed(){
 
    }
   
    @Override
    public
String toString(){
       StringBuffer stringBuff = new StringBuffer();
       stringBuff.append("\n------ Remote Control ------\n");
       for(int i=0; i<onCommands.length; i++){
           stringBuff.append("[solt "+ i +"]" +onCommands[i].getClass().getName() +

                  "    " +offCommands[i].getClass().getName() +"\n");
       }
       return stringBuff.toString();
    }
 
}
 

4.13       RemoteLoader.java 遥控器测试类

package com.gof.pattern.command;
 
public
class
RemoteLoader {
 
    public
static void
main(String[] args) {
      
       // 创建一个遥控器
       RemoteControl remoteControl = new RemoteControl();
      
       // 将所有装置创建在合适位置
       Light livingRoomLight = new Light("Living Room");
       Light kitchenLight = new Light("Kitchen");
       GarageDoor garageDoor = new GarageDoor("");
       Stereo stereo = new Stereo("Living Room");
      
       // 创建所有电灯命令对象
       ICommand livingRoomLightOn = new LightOnCommand(livingRoomLight);
       ICommand livingRoomLightOff = new LightOffCommand(livingRoomLight);
       ICommand kitchenLightOn = new LightOnCommand(kitchenLight);
       ICommand kigcchenLightOff = newLightOffCommand(kitchenLight);
       // 创建车库门上下命令对象
       ICommand garageDoorUp = new GarageDoorUpCommand(garageDoor);
       ICommand garageDoorDown = new GarageDoorDownCommand(garageDoor);
       // 创建音响开关命令对象
       ICommand stereoOnWithCDCommand = new StereoOnWithCDCommand(stereo);
       ICommand stereoOffWithCdCommand = new StereoOffWithCDCommand(stereo);
      
       // 为遥控器某个位置设置命令
       remoteControl.setCommand(0, livingRoomLightOn, livingRoomLightOff);
       remoteControl.setCommand(1, kitchenLightOn, kigcchenLightOff);
       remoteControl.setCommand(2, garageDoorUp, garageDoorDown);
       remoteControl.setCommand(3, stereoOnWithCDCommand, stereoOffWithCdCommand);
      
       System.out.println(remoteControl);
      
       // 我们按下遥控器上的1,2,3,4开关按钮测试
       remoteControl.onButtonWasPushed(0);
       remoteControl.offButtonWasPushed(0);
      
       remoteControl.onButtonWasPushed(1);
       remoteControl.offButtonWasPushed(1);
      
       remoteControl.onButtonWasPushed(2);
       remoteControl.offButtonWasPushed(2);
      
       remoteControl.onButtonWasPushed(3);
       remoteControl.offButtonWasPushed(3);
      
       remoteControl.undoButtonWasPushed();
    }
}
 

 

5      命令模式总结

5.1    优点

降低了决策逻辑的复杂性

提供了可扩展能力

能够方便地提供撤销操作

能够将多个命令放在一个队列中

能够在不同的线程或远程执行命令

5.2    缺点

在对象的创建、销毁及使用过程中可能会增加系统开销

使应用程序的结构更加复杂

5.3    指导原则

封装变化

多用组合,少用继承

针对接口编程,不针对实现编程

为交互对象之间松耦合设计而努力

类应该对扩展开发,对修改关闭

依赖抽象,不依赖具体类

命令模式:将请求封装成对象,这可以让你使用不同的请求、队列、或者日志请求来参数化其它对象。命令模式也可以支持撤销操作。

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: