本文共 4571 字,大约阅读时间需要 15 分钟。
转自:http://www.cnblogs.com/shamgod/p/4593772.html
一、概述
命令模式:客户端对服务器端发出各种命令
二、代码
1.Client.java
1 public class Client {2 3 public void request(Server server){4 server.addCommand(new TextCommand());5 server.addCommand(new ImageCommand());6 server.doSomething();7 }8 }
2.Server.java
1 public class Server { 2 3 private List commands = new ArrayList(); 4 5 public void doSomething() { 6 for(Command c : commands){ 7 c.execute(); 8 } 9 }10 11 public void addCommand(Command command) {12 commands.add(command);13 }14 15 }
3.Command.java
1 public abstract class Command {2 3 public abstract void execute();4 public abstract void unDo();5 6 }
4.TextCommand.java
1 public class TextCommand extends Command { 2 3 @Override 4 public void execute() { 5 System.out.println("TextCommand..........."); 6 } 7 8 @Override 9 public void unDo() {10 // 涉及到操作的历史记录11 }12 13 }
5.ImageCommand.java
1 public class ImageCommand extends Command { 2 3 @Override 4 public void execute() { 5 System.out.println("ImageCommand..........."); 6 } 7 8 @Override 9 public void unDo() {10 // 涉及到操作的历史记录11 }12 13 }
6.Test.java
1 public class Test {2 3 @org.junit.Test4 public void test(){5 Client c = new Client();6 c.request(new Server());7 }8 9 }
三、运行结果
转自:http://men4661273.iteye.com/blog/1633775
Command定义
将一个请求封装为一个对象,从而可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可取消的操作。
优点: 解耦了调用者和接受者之间联系。调用者调用一个操作,接受者接受请求执行相应的动作,因为使用Command模式解耦,调用者无需知道接受者任何接口。
缺点: 造成出现过多的具体命令类
代码例子如下:
播放器执行命令者:
- package command;
-
-
- public class Player {
-
- public void turnOn(){
-
- System.out.println("打开");
- }
-
- public void turnOff(){
- System.out.println("关闭");
-
- }
-
- public void next(){
-
- System.out.println("下一曲");
- }
- }
命令接口: - package command;
-
- public interface Command {
-
- public void execute();
- }
各种命令实现类: - package command;
-
- public class TurnOnCommand implements Command {
-
- private Player player;
-
- public TurnOnCommand(Player player) {
- this.player = player;
- }
-
- public void execute() {
- this.player.turnOn();
- }
-
- }
-
-
- package command;
-
- public class TurnOffCommand implements Command {
-
- private Player player;
-
- public TurnOffCommand(Player player) {
- this.player = player;
- }
-
- public void execute() {
- this.player.turnOff();
- }
-
- }
-
-
- package command;
-
- public class NextCommand implements Command {
-
- private Player player;
-
- public NextCommand(Player player) {
- this.player = player;
- }
-
- public void execute() {
- this.player.next();
- }
-
- }
命令发送者类: - package command;
-
- public class PlayerInvoker {
-
- private TurnOnCommand on;
- private TurnOffCommand off;
- private NextCommand next;
- public PlayerInvoker(TurnOnCommand on,TurnOffCommand off,NextCommand next) {
- this.on = on;
- this.off = off;
- this.next = next;
- }
-
- public void turnOn(){
- this.on.execute();
- }
-
- public void turnOff(){
- this.off.execute();
- }
-
- public void next(){
- this.next.execute();
- }
- }
测试类: - package command;
-
- public class Text {
-
- public static void main(String[] args) {
-
- Player player = new Player();
- TurnOnCommand on = new TurnOnCommand(player);
- TurnOffCommand off = new TurnOffCommand(player);
- NextCommand next = new NextCommand(player);
-
- PlayerInvoker invoker = new PlayerInvoker(on, off, next);
-
- invoker.turnOn();
- invoker.turnOff();
- invoker.next();
- }
- }
显然这样做的好处是符合封装的特性,降低耦合度,Command 是将对行为进行封装的典型模式,这样做有利于代码的健壮性 可维护性 还有复用性. Command模式通常可应用到以下场景: 1 Multi-level undo(多级undo操作) 如果系统需要实现多级回退操作,这时如果所有用户的操作都以command对象的形式实现,系统可以简 单地用stack来保存最近执行的命令,如果用户需要执行undo操作,系统只需简单地popup一个最近的 command对象然后执行它的undo()方法既可。 2 Transactional behavior(原子事务行为) 借助command模式,可以简单地实现一个具有原子事务的行为。当一个事务失败时,往往需要回退到执 行前的状态,可以借助command对象保存这种状态,简单地处理回退操作。 3 Progress bars(状态条) 假如系统需要按顺序执行一系列的命令操作,如果每个command对象都提供一个 getEstimatedDuration()方法,那么系统可以简单地评估执行状态并显示出合适的状态条。 4 Wizards(导航) 通常一个使用多个wizard页面来共同完成一个简单动作。一个自然的方法是使用一个command对象来封 装wizard过程,该command对象在第一个wizard页面显示时被创建,每个wizard页面接收用户输入并设 置到该command对象中,当最后一个wizard页面用户按下“Finish”按钮时,可以简单地触发一个事件 调用execute()方法执行整个动作。通过这种方法,command类不包含任何跟用户界面有关的代码,可以 分离用户界面与具体的处理逻辑。 5 GUI buttons and menu items(GUI按钮与菜单条等等) Swing系统里,用户可以通过工具条按钮,菜单按钮执行命令,可以用command对象来封装命令的执行。 6 Thread pools(线程池) 通常一个典型的线程池实现类可能有一个名为addTask()的public方法,用来添加一项工作任务到任务 队列中。该任务队列中的所有任务可以用command对象来封装,通常这些command对象会实现一个通用的 接口比如java.lang.Runnable。 7 Macro recording(宏纪录) 可以用command对象来封装用户的一个操作,这样系统可以简单通过队列保存一系列的command对象的状 态就可以记录用户的连续操作。这样通过执行队列中的command对象,就可以完成"Play back"操作了。 8 Networking 通过网络发送command命令到其他机器上运行。 9 Parallel Processing(并发处理) 当一个调用共享某个资源并被多个线程并发处理时。