一、

1.因为是操作经常变化,所以封装操作为command对象。You can do that by introducing “command objects” into your design. A command object encapsulates a request to do something (like turn on a light) on a specific object (say, the living room light object). So, if we store a command object for each button, when the button is pressed we ask the command object to do some work. The remote doesn’t have any idea what the work is, it just has a command object that knows how to talk to the right object to get the work done.So, you see, the remote is decoupled from the light object!

2.The Command Pattern encapsulates a request as an object, thereby letting you parameterize other objects

with different requests, queue or log requests, and support undoable operations.

3.When you need to decouple an object making requests from the objects that know how to perform the requests, use

the Command Pattern.

3.

4.

5.

6.

7.

8.

二、简单命令模式

1.

package headfirst.designpatterns.command.simpleremote;

public interface Command {
public void execute();
}

2.

 package headfirst.designpatterns.command.simpleremote;

 public class LightOnCommand implements Command {
Light light; public LightOnCommand(Light light) {
this.light = light;
} public void execute() {
light.on();
}
}

3.

 package headfirst.designpatterns.command.simpleremote;

 public class Light {

     public Light() {
} public void on() {
System.out.println("Light is on");
} public void off() {
System.out.println("Light is off");
}
}

4.

 package headfirst.designpatterns.command.simpleremote;

 //
// This is the invoker
//
public class SimpleRemoteControl {
Command slot; public SimpleRemoteControl() {} public void setCommand(Command command) {
slot = command;
} public void buttonWasPressed() {
slot.execute();
}
}

5.

 package headfirst.designpatterns.command.simpleremote;

 public class RemoteControlTest {
public static void main(String[] args) {
SimpleRemoteControl remote = new SimpleRemoteControl();
Light light = new Light();
GarageDoor garageDoor = new GarageDoor();
LightOnCommand lightOn = new LightOnCommand(light);
GarageDoorOpenCommand garageOpen =
new GarageDoorOpenCommand(garageDoor); remote.setCommand(lightOn);
remote.buttonWasPressed();
remote.setCommand(garageOpen);
remote.buttonWasPressed();
} }

三、远程调用命令模式

1.

 package headfirst.designpatterns.command.remote;

 public class RemoteLoader {

     public static void main(String[] args) {
RemoteControl remoteControl = new RemoteControl(); Light livingRoomLight = new Light("Living Room");
Light kitchenLight = new Light("Kitchen");
CeilingFan ceilingFan= new CeilingFan("Living Room");
GarageDoor garageDoor = new GarageDoor("");
Stereo stereo = new Stereo("Living Room"); LightOnCommand livingRoomLightOn =
new LightOnCommand(livingRoomLight);
LightOffCommand livingRoomLightOff =
new LightOffCommand(livingRoomLight);
LightOnCommand kitchenLightOn =
new LightOnCommand(kitchenLight);
LightOffCommand kitchenLightOff =
new LightOffCommand(kitchenLight); CeilingFanOnCommand ceilingFanOn =
new CeilingFanOnCommand(ceilingFan);
CeilingFanOffCommand ceilingFanOff =
new CeilingFanOffCommand(ceilingFan); GarageDoorUpCommand garageDoorUp =
new GarageDoorUpCommand(garageDoor);
GarageDoorDownCommand garageDoorDown =
new GarageDoorDownCommand(garageDoor); StereoOnWithCDCommand stereoOnWithCD =
new StereoOnWithCDCommand(stereo);
StereoOffCommand stereoOff =
new StereoOffCommand(stereo); remoteControl.setCommand(0, livingRoomLightOn, livingRoomLightOff);
remoteControl.setCommand(1, kitchenLightOn, kitchenLightOff);
remoteControl.setCommand(2, ceilingFanOn, ceilingFanOff);
remoteControl.setCommand(3, stereoOnWithCD, stereoOff); System.out.println(remoteControl); remoteControl.onButtonWasPushed(0);
remoteControl.offButtonWasPushed(0);
remoteControl.onButtonWasPushed(1);
remoteControl.offButtonWasPushed(1);
remoteControl.onButtonWasPushed(2);
remoteControl.offButtonWasPushed(2);
remoteControl.onButtonWasPushed(3);
remoteControl.offButtonWasPushed(3);
}
}

2.

 package headfirst.designpatterns.command.remote;

 //
// This is the invoker
//
public class RemoteControl {
Command[] onCommands;
Command[] offCommands; public RemoteControl() {
onCommands = new Command[7];
offCommands = new Command[7]; Command noCommand = new NoCommand();
for (int i = 0; i < 7; i++) {
onCommands[i] = noCommand;
offCommands[i] = noCommand;
}
} public void setCommand(int slot, Command onCommand, Command offCommand) {
onCommands[slot] = onCommand;
offCommands[slot] = offCommand;
} public void onButtonWasPushed(int slot) {
onCommands[slot].execute();
} public void offButtonWasPushed(int slot) {
offCommands[slot].execute();
} public String toString() {
StringBuffer stringBuff = new StringBuffer();
stringBuff.append("\n------ Remote Control -------\n");
for (int i = 0; i < onCommands.length; i++) {
stringBuff.append("[slot " + i + "] " + onCommands[i].getClass().getName()
+ " " + offCommands[i].getClass().getName() + "\n");
}
return stringBuff.toString();
}
}

3.

 package headfirst.designpatterns.command.remote;

 public class Stereo {
String location; public Stereo(String location) {
this.location = location;
} public void on() {
System.out.println(location + " stereo is on");
} public void off() {
System.out.println(location + " stereo is off");
} public void setCD() {
System.out.println(location + " stereo is set for CD input");
} public void setDVD() {
System.out.println(location + " stereo is set for DVD input");
} public void setRadio() {
System.out.println(location + " stereo is set for Radio");
} public void setVolume(int volume) {
// code to set the volume
// valid range: 1-11 (after all 11 is better than 10, right?)
System.out.println(location + " Stereo volume set to " + volume);
}
}

4.

 package headfirst.designpatterns.command.remote;

 public class StereoOnWithCDCommand implements Command {
Stereo stereo; public StereoOnWithCDCommand(Stereo stereo) {
this.stereo = stereo;
} public void execute() {
stereo.on();
stereo.setCD();
stereo.setVolume(11);
}
}

5.

四、有undo功能的命令模式

1.

 package headfirst.designpatterns.command.undo;

 public class RemoteLoader {

     public static void main(String[] args) {
RemoteControlWithUndo remoteControl = new RemoteControlWithUndo(); Light livingRoomLight = new Light("Living Room"); LightOnCommand livingRoomLightOn =
new LightOnCommand(livingRoomLight);
LightOffCommand livingRoomLightOff =
new LightOffCommand(livingRoomLight); remoteControl.setCommand(0, livingRoomLightOn, livingRoomLightOff); remoteControl.onButtonWasPushed(0);
remoteControl.offButtonWasPushed(0);
System.out.println(remoteControl);
remoteControl.undoButtonWasPushed();
remoteControl.offButtonWasPushed(0);
remoteControl.onButtonWasPushed(0);
System.out.println(remoteControl);
remoteControl.undoButtonWasPushed(); CeilingFan ceilingFan = new CeilingFan("Living Room"); CeilingFanMediumCommand ceilingFanMedium =
new CeilingFanMediumCommand(ceilingFan);
CeilingFanHighCommand ceilingFanHigh =
new CeilingFanHighCommand(ceilingFan);
CeilingFanOffCommand ceilingFanOff =
new CeilingFanOffCommand(ceilingFan); remoteControl.setCommand(0, ceilingFanMedium, ceilingFanOff);
remoteControl.setCommand(1, ceilingFanHigh, ceilingFanOff); remoteControl.onButtonWasPushed(0);
remoteControl.offButtonWasPushed(0);
System.out.println(remoteControl);
remoteControl.undoButtonWasPushed(); remoteControl.onButtonWasPushed(1);
System.out.println(remoteControl);
remoteControl.undoButtonWasPushed();
}
}

2.

 package headfirst.designpatterns.command.undo;

 //
// This is the invoker
//
public class RemoteControlWithUndo {
Command[] onCommands;
Command[] offCommands;
Command undoCommand; public RemoteControlWithUndo() {
onCommands = new Command[7];
offCommands = new Command[7]; Command noCommand = new NoCommand();
for(int i=0;i<7;i++) {
onCommands[i] = noCommand;
offCommands[i] = noCommand;
}
undoCommand = noCommand;
} public void setCommand(int slot, Command onCommand, Command offCommand) {
onCommands[slot] = onCommand;
offCommands[slot] = offCommand;
} public void onButtonWasPushed(int slot) {
onCommands[slot].execute();
undoCommand = onCommands[slot];
} public void offButtonWasPushed(int slot) {
offCommands[slot].execute();
undoCommand = offCommands[slot];
} public void undoButtonWasPushed() {
undoCommand.undo();
} public String toString() {
StringBuffer stringBuff = new StringBuffer();
stringBuff.append("\n------ Remote Control -------\n");
for (int i = 0; i < onCommands.length; i++) {
stringBuff.append("[slot " + i + "] " + onCommands[i].getClass().getName()
+ " " + offCommands[i].getClass().getName() + "\n");
}
stringBuff.append("[undo] " + undoCommand.getClass().getName() + "\n");
return stringBuff.toString();
}
}

3.

 package headfirst.designpatterns.command.undo;

 public class NoCommand implements Command {
public void execute() { }
public void undo() { }
}

4.

 package headfirst.designpatterns.command.undo;

 public class Light {
String location;
int level; public Light(String location) {
this.location = location;
} public void on() {
level = 100;
System.out.println("Light is on");
} public void off() {
level = 0;
System.out.println("Light is off");
} public void dim(int level) {
this.level = level;
if (level == 0) {
off();
}
else {
System.out.println("Light is dimmed to " + level + "%");
}
} public int getLevel() {
return level;
}
}

5.

package headfirst.designpatterns.command.undo;

public class LightOffCommand implements Command {
Light light;
int level;
public LightOffCommand(Light light) {
this.light = light;
} public void execute() {
level = light.getLevel();
light.off();
} public void undo() {
light.dim(level);
}
}

6.

 package headfirst.designpatterns.command.undo;

 public class LightOnCommand implements Command {
Light light;
int level;
public LightOnCommand(Light light) {
this.light = light;
} public void execute() {
level = light.getLevel();
light.on();
} public void undo() {
light.dim(level);
}
}

7.

 package headfirst.designpatterns.command.undo;

 public class CeilingFan {
public static final int HIGH = 3;
public static final int MEDIUM = 2;
public static final int LOW = 1;
public static final int OFF = 0;
String location;
int speed; public CeilingFan(String location) {
this.location = location;
speed = OFF;
} public void high() {
speed = HIGH;
System.out.println(location + " ceiling fan is on high");
} public void medium() {
speed = MEDIUM;
System.out.println(location + " ceiling fan is on medium");
} public void low() {
speed = LOW;
System.out.println(location + " ceiling fan is on low");
} public void off() {
speed = OFF;
System.out.println(location + " ceiling fan is off");
} public int getSpeed() {
return speed;
}
}

8.

 package headfirst.designpatterns.command.undo;

 public class CeilingFanHighCommand implements Command {
CeilingFan ceilingFan;
int prevSpeed; public CeilingFanHighCommand(CeilingFan ceilingFan) {
this.ceilingFan = ceilingFan;
} public void execute() {
prevSpeed = ceilingFan.getSpeed();
ceilingFan.high();
} public void undo() {
if (prevSpeed == CeilingFan.HIGH) {
ceilingFan.high();
} else if (prevSpeed == CeilingFan.MEDIUM) {
ceilingFan.medium();
} else if (prevSpeed == CeilingFan.LOW) {
ceilingFan.low();
} else if (prevSpeed == CeilingFan.OFF) {
ceilingFan.off();
}
}
}

9.

 package headfirst.designpatterns.command.undo;

 public class CeilingFanLowCommand implements Command {
CeilingFan ceilingFan;
int prevSpeed; public CeilingFanLowCommand(CeilingFan ceilingFan) {
this.ceilingFan = ceilingFan;
} public void execute() {
prevSpeed = ceilingFan.getSpeed();
ceilingFan.low();
} public void undo() {
if (prevSpeed == CeilingFan.HIGH) {
ceilingFan.high();
} else if (prevSpeed == CeilingFan.MEDIUM) {
ceilingFan.medium();
} else if (prevSpeed == CeilingFan.LOW) {
ceilingFan.low();
} else if (prevSpeed == CeilingFan.OFF) {
ceilingFan.off();
}
}
}

五、全部关或开

1.

 package headfirst.designpatterns.command.party;

 public class RemoteLoader {

     public static void main(String[] args) {

         RemoteControl remoteControl = new RemoteControl();

         Light light = new Light("Living Room");
TV tv = new TV("Living Room");
Stereo stereo = new Stereo("Living Room");
Hottub hottub = new Hottub(); LightOnCommand lightOn = new LightOnCommand(light);
StereoOnCommand stereoOn = new StereoOnCommand(stereo);
TVOnCommand tvOn = new TVOnCommand(tv);
HottubOnCommand hottubOn = new HottubOnCommand(hottub);
LightOffCommand lightOff = new LightOffCommand(light);
StereoOffCommand stereoOff = new StereoOffCommand(stereo);
TVOffCommand tvOff = new TVOffCommand(tv);
HottubOffCommand hottubOff = new HottubOffCommand(hottub); Command[] partyOn = { lightOn, stereoOn, tvOn, hottubOn};
Command[] partyOff = { lightOff, stereoOff, tvOff, hottubOff}; MacroCommand partyOnMacro = new MacroCommand(partyOn);
MacroCommand partyOffMacro = new MacroCommand(partyOff); remoteControl.setCommand(0, partyOnMacro, partyOffMacro); System.out.println(remoteControl);
System.out.println("--- Pushing Macro On---");
remoteControl.onButtonWasPushed(0);
System.out.println("--- Pushing Macro Off---");
remoteControl.offButtonWasPushed(0);
}
}

2.

 package headfirst.designpatterns.command.party;

 public class MacroCommand implements Command {
Command[] commands; public MacroCommand(Command[] commands) {
this.commands = commands;
} public void execute() {
for (int i = 0; i < commands.length; i++) {
commands[i].execute();
}
} /**
* NOTE: these commands have to be done backwards to ensure
* proper undo functionality
*/
public void undo() {
for (int i = commands.length -1; i >= 0; i--) {
commands[i].undo();
}
}
}

3.

 package headfirst.designpatterns.command.party;

 //
// This is the invoker
//
public class RemoteControl {
Command[] onCommands;
Command[] offCommands;
Command undoCommand; public RemoteControl() {
onCommands = new Command[7];
offCommands = new Command[7]; Command noCommand = new NoCommand();
for(int i=0;i<7;i++) {
onCommands[i] = noCommand;
offCommands[i] = noCommand;
}
undoCommand = noCommand;
} public void setCommand(int slot, Command onCommand, Command offCommand) {
onCommands[slot] = onCommand;
offCommands[slot] = offCommand;
} public void onButtonWasPushed(int slot) {
onCommands[slot].execute();
undoCommand = onCommands[slot];
} public void offButtonWasPushed(int slot) {
offCommands[slot].execute();
undoCommand = offCommands[slot];
} public void undoButtonWasPushed() {
undoCommand.undo();
} public String toString() {
StringBuffer stringBuff = new StringBuffer();
stringBuff.append("\n------ Remote Control -------\n");
for (int i = 0; i < onCommands.length; i++) {
stringBuff.append("[slot " + i + "] " + onCommands[i].getClass().getName()
+ " " + offCommands[i].getClass().getName() + "\n");
}
stringBuff.append("[undo] " + undoCommand.getClass().getName() + "\n");
return stringBuff.toString();
}
}

4.

 package headfirst.designpatterns.command.party;

 public class CeilingFanHighCommand implements Command {
CeilingFan ceilingFan;
int prevSpeed; public CeilingFanHighCommand(CeilingFan ceilingFan) {
this.ceilingFan = ceilingFan;
}
public void execute() {
prevSpeed = ceilingFan.getSpeed();
ceilingFan.high();
}
public void undo() {
switch (prevSpeed) {
case CeilingFan.HIGH: ceilingFan.high(); break;
case CeilingFan.MEDIUM: ceilingFan.medium(); break;
case CeilingFan.LOW: ceilingFan.low(); break;
default: ceilingFan.off(); break;
}
}
}

六、命令模式的其他作用

1.queuing requests

2.logging requests

HeadFirst设计模式之命令模式的更多相关文章

  1. 设计模式 ( 十三 ) 命令模式Command(对象行为型)

    设计模式 ( 十三 ) 命令模式Command(对象行为型) 1.概述         在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个,我们只需 ...

  2. 乐在其中设计模式(C#) - 命令模式(Command Pattern)

    原文:乐在其中设计模式(C#) - 命令模式(Command Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 命令模式(Command Pattern) 作者:webabcd ...

  3. 面向对象设计模式_命令模式(Command)解读

    在.Net框架中很多对象的方法中都会有Invoke方法,这种方法的设计实际是用了设计模式的命令模式, 模式图如下 其核心思路是将Client 向Receiver发送的命令行为进行抽象(ICommand ...

  4. 折腾Java设计模式之命令模式

    博客原文地址 折腾Java设计模式之命令模式 命令模式 wiki上的描述 Encapsulate a request as an object, thereby allowing for the pa ...

  5. 用Java 8 Lambda表达式实现设计模式:命令模式

    在这篇博客里,我将说明如何在使用 Java 8 Lambda表达式 的函数式编程方式 时实现 命令 设计模式 .命令模式的目标是将请求封装成一个对象,从对客户端的不同类型请求,例如队列或日志请求参数化 ...

  6. python设计模式之命令模式

    python设计模式之命令模式 现在多数应用都有撤销操作.虽然难以想象,但在很多年里,任何软件中确实都不存在撤销操作.撤销操作是在1974年引入的,但Fortran和Lisp分别早在1957年和195 ...

  7. Head First 设计模式 --6 命令模式

    命令模式:将"请求"封装成对象,以便使用不同的请求,队列或者日志来参数化其他对象.命令模式也支持可撤销的操作.用到的原则:1.封装变化2.组合优于继承3.针对接口编程,不能针对实现 ...

  8. C#设计模式(15)——命令模式(Command Pattern)

    一.前言 之前一直在忙于工作上的事情,关于设计模式系列一直没更新,最近项目中发现,对于设计模式的了解是必不可少的,当然对于设计模式的应用那更是重要,可以说是否懂得应用设计模式在项目中是衡量一个程序员的 ...

  9. 【GOF23设计模式】命令模式

    来源:http://www.bjsxt.com/ 一.[GOF23设计模式]_命令模式.数据库事务机制底层架构实现.撤销和回复 package com.test.command; public cla ...

随机推荐

  1. 【转载】干货再次来袭!Linux小白最佳实践:《超容易的Linux系统管理入门书》(连载八)用命令实现批量添加用户

    Windows添加用户需要至少5个界面,而Linux一条命令就搞定了,这是不是高效人士办公第一法则呢.本文不给你一堆参数和选项,不让你见识教条主义,只给你最实用的代码. 想每天能听到小妞的语音播报,想 ...

  2. Js 对象二

    一.Date对象 1.创建Date对象的方法 1)使用new关键字和Date类来创建(不带参数) Var today = new Date(); //不带参数 它是获取当前的系统时间 2)使用new关 ...

  3. C++与Lua交互(二)

    上一篇我们搭建好了整个的项目环境,现在,我们一起探索一下如何将lua寄宿到C++中. 宿主的实现 我们在LuaWithCPPTest项目下,查看Source.cpp代码如下: #include < ...

  4. Mysql slave 同步错误解决

    涉及知识点 mysql 主从同步 ,参考: MySQL数据库设置主从同步 mysqlbin log查看, 参考:MySQL的binlog日志 解决slave报错, 参考: Backup stopped ...

  5. initial,常用于消除css格式

    刚在群里有人问在不改变原有css的情况下怎么清除一个css属性.有人提出了 initial,再此记录下. initial 关键字用于设置 CSS 属性为它的默认值. initial 关键字可用于任何 ...

  6. 数据库连接池c3p0和dbcp

    现在常用的开源数据连接池主要有c3p0.dbcp和proxool三种,其中: hibernate开发组推荐使用c3p0; spring开发组推荐使用dbcp(dbcp连接池有weblogic连接池同样 ...

  7. ToolStripStatusLabel设置时间自动更新

    在使用委托设置界面上ToolStripStatusLabel类型的控件时间是,发现不能使用自定义的委托方法,在往上查找了一下发现不能使用involve来线程调用.因此只能使用原生委托方法. //代理p ...

  8. CorelDRAW 插件的安装和使用

    CorelDRAW 是一款在中国非常受欢迎的图形软件,开放的界面和编程技术,能够对它进行二次开发制作插件,插件大抵有三种gms.cpg.exe格式,下面介绍一下这三种插件的安装和使用方法. 一.gms ...

  9. CentOS7安装性能监控系统

    目录 系统描述. 开发环境. 开始之前. 安装influxdb数据库. 安装collectd 安装Grafana FAQ       influxdb的web界面没反应.   系统描述 想打造 New ...

  10. Nagios脚本编写事例

    目标:编写一个简单的nagios脚本,实现监控client上的nginx进程是否启动,假如没启动的话发出报警. 首先在master上对nagios的配置文件进行设置,修改services.cfg文件, ...