Java设计模式之命令模式

转载 2015年07月10日 17:36:07

转载

原创此处

主题

定义

  将来自客户端的请求传入一个对象,从而使你可用不同的请求对客户进行参数化。用于“行为请求者”与“行为实现者”解耦,可实现二者之间的松耦合,以便适应变化。分离变化与不变的因素。

角色

  • Command  定义命令的接口,声明执行的方法。
  • ConcreteCommand  命令接口实现对象,是“虚”的实现;通常会持有接收者,并调用接收者的功能来完成命令要执行的操作。
  • Receiver  接收者,真正执行命令的对象。任何类都可能成为一个接收者,只要它能够实现命令要求实现的相应功能。
  • Invoker  要求命令对象执行请求,通常会持有命令对象,可以持有很多的命令对象。这个是客户端真正触发命令并要求命令执行相应操作的地方,也就是说相当于使用命令对象的入口。
  • Client  创建具体的命令对象,并且设置命令对象的接收者。注意这个不是我们常规意义上的客户端,而是在组装命令对象和接收者,或许,把这个Client称为装配者会更好理解,因为真正使用命令的客户端是从Invoker来触发执行。

优点

  1. 降低对象之间的耦合度。
  2. 新的命令可以很容易地加入到系统中。
  3. 可以比较容易地设计一个组合命令。
  4. 调用同一方法实现不同的功能

缺点

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

适用情况

  1. 系统需要将请求调用者和请求接收者解耦,使得调用者和接收者不直接交互。
  2. 系统需要在不同的时间指定请求、将请求排队和执行请求。
  3. 系统需要支持命令的撤销(Undo)操作和恢复(Redo)操作。
  4. 系统需要将一组操作组合在一起,即支持宏命令。

应用

模拟对电视机的操作有开机、关机、换台命令。代码如下

java

//执行命令的接口  
public interface Command {  
  void execute();  
}  
java

//命令接收者Receiver  
public class Tv {  
  public int currentChannel = 0;  

  public void turnOn() {  
     System.out.println("The televisino is on.");  
  }  

  public void turnOff() {  
     System.out.println("The television is off.");  
  }  

  public void changeChannel(int channel) {  
     this.currentChannel = channel;  
     System.out.println("Now TV channel is " + channel);  
  }  
} 
java

//开机命令ConcreteCommand  
public class CommandOn implements Command {  
  private Tv myTv;  

  public CommandOn(Tv tv) {  
     myTv = tv;  
  }  

  public void execute() {  
     myTv.turnOn();  
  }  
}  
java

//关机命令ConcreteCommand  
public class CommandOff implements Command {  
  private Tv myTv;  

  public CommandOff(Tv tv) {  
     myTv = tv;  
  }  

  public void execute() {  
     myTv.turnOff();  
  }  
}  
java

//频道切换命令ConcreteCommand  
public class CommandChange implements Command {  
  private Tv myTv;  

  private int channel;  

  public CommandChange(Tv tv, int channel) {  
     myTv = tv;  
     this.channel = channel;  
  }  

  public void execute() {  
     myTv.changeChannel(channel);  
  }  
}  
java

//可以看作是遥控器Invoker  
public class Control {  
  private Command onCommand, offCommand, changeChannel;  

  public Control(Command on, Command off, Command channel) {  
     onCommand = on;  
     offCommand = off;  
     changeChannel = channel;  
  }  

  public void turnOn() {  
     onCommand.execute();  
  }  

  public void turnOff() {  
     offCommand.execute();  
  }  

  public void changeChannel() {  
     changeChannel.execute();  
  }  
}  
java

//测试类Client  
public class Client {  
  public static void main(String[] args) {  
     // 命令接收者Receiver  
     Tv myTv = new Tv();  
     // 开机命令ConcreteCommond  
     CommandOn on = new CommandOn(myTv);  
     // 关机命令ConcreteCommond  
     CommandOff off = new CommandOff(myTv);  
     // 频道切换命令ConcreteCommond  
     CommandChange channel = new CommandChange(myTv, 2);  
     // 命令控制对象Invoker  
     Control control = new Control(on, off, channel);  

     // 开机  
     control.turnOn();  
     // 切换频道  
     control.changeChannel();  
     // 关机  
     control.turnOff();  
  }  
}  



执行结果

The televisino is on.  
Now TV channel is 2  
The television is off. 

总结

  1. 命令模式的本质是对命令进行封装,将发出命令的责任和执行命令的责任分割开。
  2. 每一个命令都是一个操作:请求的一方发出请求,要求执行一个操作;接收的一方收到请求,并执行操作。
  3. 命令模式允许请求的一方和接收的一方独立开来,使得请求的一方不必知道接收请求的一方的接口,更不必知道请求是怎么被接收,以及操作是否被执行、何时被执行,以及是怎么被执行的。
  4. 命令模式使请求本身成为一个对象,这个对象和其他对象一样可以被存储和传递。
  5. 命令模式的关键在于引入了抽象命令接口,且发送者针对抽象命令接口编程,只有实现了抽象命令接口的具体命令才能与接收者相关联。

Java开发中的23种设计模式详解----命令模式(Command)

命令模式很好理解,举个例子,司令员下令让士兵去干件事情,从整个事情的角度来考虑,司令员的作用是,发出口令,口令经过传递,传到了士兵耳朵里,士兵去执行。这个过程好在,三者相互解耦,任何一方都不用去依赖其...
  • sjyttkl
  • sjyttkl
  • 2017年06月21日 12:23
  • 919

Java设计模式之命令模式

继续23种设计模式系列,本文介绍命令模式。
  • jason0539
  • jason0539
  • 2015年04月19日 08:31
  • 21592

设计模式 —— 命令模式(Command Pattern)

命令模式(Command Pattern)概念: 概述:在软件设计中,我们经常会遇到某些对象发送请求,然后某些对象接受请求后执行,但发送请求的对象可能并不知道接受请求的对象是谁,执行的是什么动作。...
  • wwh578867817
  • wwh578867817
  • 2016年05月29日 18:34
  • 1217

iOS设计模式(九) 命令模式

可以把一系列动作封装成一个命令,在用户不需要知道其实现细节,使用细节的情况下就可以调用。 一般在想让应用程序支持撤销与恢复的情况下使用这一模式。 在OC中NSInvocation和NSUndoMa...
  • a2331046
  • a2331046
  • 2016年07月11日 14:43
  • 269

设计模式(行为型)之命令模式(Command Pattern)

在软件开发中,我们经常需要向某些对象发送请求(调用其中的某个或某些方法),但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个,此时,我们特别希望能够以一种松耦合的方式来设计软件,使得请求发送者与...
  • yanbober
  • yanbober
  • 2015年05月05日 11:49
  • 3159

设计模式之命令模式---Command Pattern

模式的定义命令模式是一个高内聚的模式,定义如下:Encapsulate a request as an object,thereby letting you parameterize clients ...
  • hfreeman2008
  • hfreeman2008
  • 2016年08月06日 10:37
  • 1582

iOS 设计模式 - 命令模式

在软件系统中,“行为请求者”与“行为实现者”通常呈现一种“紧耦合”。但在某些场合,比如要对行为进行“记录、撤销/重做、事务”等处理,这种无法抵御变化的紧耦合是不合适的。在这种情况下,如何将“行为请求者...
  • Seal_Shile
  • Seal_Shile
  • 2016年02月25日 23:02
  • 457

Java设计模式——命令模式(Command)

定义:      将一个请求封装为一个对象或者操作封装到一个对象中,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。     是对命令的封装,把发出命令的责任和...
  • u014805893
  • u014805893
  • 2016年11月24日 22:38
  • 225

深入浅出设计模式之命令模式、适配器模式、外观模式

命令模式
  • u011531613
  • u011531613
  • 2017年03月22日 20:42
  • 479

浅谈JAVA设计模式之——命令模式(Command)

一、概述 将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤消的操作。 二、适用性 1.抽象出待执行的动作以参数化某对象。 2.在不同的时刻指...
  • l1028386804
  • l1028386804
  • 2015年05月08日 00:22
  • 4067
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Java设计模式之命令模式
举报原因:
原因补充:

(最多只允许输入30个字)