命令模式:
将“请求”封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象。命令模式也支持可撤销的操作。
涉及设计原则:
1.为交互对象之间松耦合设计而努力
2.依赖抽象,不要依赖具体类
问题简单描述:
需要实现一个遥控器,控制不同硬件的功能。因为遥控器以后可能需要新增对其他硬件的控制,如果遥控器知道太多硬件的细节(依赖实体类),每增加一个硬件都需要对遥控器进行修改。
解决思路:
引进一个“傻瓜”命令对象,命令对象只需要执行简单的方法。遥控器中设置命令对象,命令对象依赖具体的硬件操作,实现遥控器与硬件操作的解耦。
UML图:
实现代码:
Receiver类
package command;
/**
* 电灯(receiver)
* @author terry
*
*/
public class Light {
private String description;
public Light() {
super();
}
public Light(String description) {
super();
this.description = description;
}
public void on(){
System.out.println("Light is on");
}
public void off(){
System.out.println("Light is off");
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
package command;
public class TV {
private boolean power;
private Integer volumnNow;
private String description;
public TV() {
super();
volumnNow=5;
power=false;
}
public TV(String description) {
super();
this.description = description;
volumnNow=5;
power=false;
}
public void on(){
System.out.println("TV is on");
power=true;
}
public void off(){
System.out.println("TV is off");
power=false;
}
public void turnUpVolumn(){
if(power){
System.out.println("TV's volumn has changed from "+volumnNow+" to "+ (++volumnNow));
}else{
System.out.println("TV is off");
}
}
public void turnDownVolumn(){
if(power){
System.out.println("TV's volumn has changed from "+volumnNow+" to "+ (--volumnNow));
}else{
System.out.println("TV is off");
}
}
public Integer getVolumnNow() {
return volumnNow;
}
public void setVolumnNow(Integer volumnNow) {
this.volumnNow = volumnNow;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
Command接口
package command;
/**
* 命令接口
* author terry
*
*/
public interface Command {
//执行
public void execute();
//撤销
public void undo();
}
Command实现类
package command;
public class LightOnCommand implements Command{
Light light;
public LightOnCommand(Light light) {
super();
this.light = light;
}
@Override
public void execute() {
light.on();
}
@Override
public void undo() {
light.off();
}
}
package command;
public class LightOffCommand implements Command {
Light light;
public LightOffCommand(Light light) {
super();
this.light = light;
}
@Override
public void execute() {
light.off();
}
@Override
public void undo() {
light.on();
}
}
package command;
public class TVOnCommand implements Command{
TV tv;
public TVOnCommand(TV tv) {
super();
this.tv = tv;
}
@Override
public void execute() {
tv.on();
}
@Override
public void undo() {
tv.off();
}
}
package command;
public class TVOffCommand implements Command {
TV tv;
public TVOffCommand(TV tv) {
super();
this.tv = tv;
}
@Override
public void execute() {
tv.off();
}
@Override
public void undo() {
tv.on();
}
}
package command;
public class TVTurnUpVolumnCommand implements Command{
TV tv;
public TVTurnUpVolumnCommand(TV tv) {
super();
this.tv = tv;
}
@Override
public void execute() {
tv.turnUpVolumn();
}
@Override
public void undo() {
tv.turnDownVolumn();
}
}
package command;
public class TVTurnDownVolumnCommand implements Command{
TV tv;
public TVTurnDownVolumnCommand(TV tv) {
super();
this.tv = tv;
}
@Override
public void execute() {
tv.turnDownVolumn();
}
@Override
public void undo() {
tv.turnUpVolumn();
}
}
Client(测试类)
package command;
public class Test {
public static void main(String[] args) {
//创建遥控器
Invoker invoker=new Invoker();
//绑定命令(1.将receiver绑定到command中 2.invoker调用setCommand设置command)
Light light=new Light();
LightOnCommand lightOnCommand=new LightOnCommand(light);
LightOffCommand lightOffCommand=new LightOffCommand(light);
invoker.setCommand(0, lightOnCommand);
invoker.setCommand(1, lightOffCommand);
TV tv=new TV();
TVOnCommand tvOnCommand=new TVOnCommand(tv);
TVOffCommand tvOffCommand=new TVOffCommand(tv);
TVTurnDownVolumnCommand tvTurnDownVolumnCommand=new TVTurnDownVolumnCommand(tv);
TVTurnUpVolumnCommand tvTurnUpVolumnCommand=new TVTurnUpVolumnCommand(tv);
invoker.setCommand(2, tvOnCommand);
invoker.setCommand(3, tvOffCommand);
invoker.setCommand(4, tvTurnDownVolumnCommand);
invoker.setCommand(5, tvTurnUpVolumnCommand);
System.out.println(invoker.toString());
System.out.println("====================action====================");
invoker.buttonPushed(0);
invoker.buttonPushed(1);
invoker.buttonPushed(2);
invoker.buttonPushed(4);
invoker.buttonPushed(5);
invoker.buttonPushed(3);
System.out.println("====================undo====================");
invoker.undo();
invoker.undo();
invoker.undo();
invoker.undo();
invoker.undo();
invoker.undo();
}
}
又是一个通过抽象松耦合的模式。原来只是client通过invoker'操作receiver的一个流程,引进的Command这样的“傻瓜”抽象层,使得invoker与receiver解耦。命令模式中,invoker只要调用command的execute就好了,不需要知道具体是什么command,command是怎么实现execute的,觉得有点像工厂模式的感觉,毕竟都是依赖了抽象解耦。觉得这就是架构的美,添加了一些多余的代码,虽然让不熟悉的人觉得可能降低了代码可读性,但是却为以后需求变化的代码修改做出了巨大便利。
欢迎批评指正^ ^