标签:
命令模式(Command Pattern),是行为型模式之一。在日常生活和开发过程中,这是一个非常常见的设计模式,比如我们电脑关机这个操作,我们只需要点击关机键便可以实现关机,内部是通过什么进行关机的,我们不需要去知道,计算机会帮我们实现这个功能。
优点:
(1)比较容易地实现一个命令队列。
(2)比较容易将队列记入日志。
(3)请求者和实现者通过接口进一步解耦。
(4)可以容易地实现对请求的撤销和恢复。
(5)加入新的命令不影响其它类的操作。
引用上述关机的例子,对名词进行一些解释:
·Client(客户端):此处为我们自己,创建一个具体命令(ConcreteCommand)对象并确定其接收者。
·Invoker(请求者):关机键,负责调用命令对象执行请求,相关的方法叫做行动方法。
·Command(命令):声明了一个给所有具体命令类的抽象接口。
·ConcreteCommand(具体命令):调用关机的操作。
·Receicer(接收者):实现关机的操作。
接收者角色类
1 public class Receiver 2 { 3 /** 4 * 真正执行命令相应的操作 5 */ 6 public void action(){ 7 System.out.println("执行操作"); 8 } 9 }
抽象命令角色类
1 public interface Command 2 { 3 void execute(); 4 }
具体命令角色类
1 public class ConcreteCommand implements Command 2 { 3 private Receiver receiver; 4 5 public ConcreteCommand(Receiver receiver) 6 { 7 this.receiver = receiver; 8 } 9 10 public void execute() { 11 // 调用并执行命令 12 receiver.action(); 13 } 14 }
请求者角色类
1 public class Invoker 2 { 3 private Command command; 4 5 public Invoker(Command command) 6 { 7 this.command = command; 8 } 9 10 /** 11 * 行动方法,和Receive中的action()方法名称相同,却没有半毛钱关系 12 */ 13 public void action(){ 14 15 command.execute(); 16 } 17 }
客户端
1 public class Client 2 { 3 4 /** 5 * created by zm on 16-05-22 6 */ 7 public static void main(String[] args) { 8 // TODO Auto-generated method stub 9 //创建接收者 10 Receiver receiver = new Receiver(); 11 //创建命令对象,设定它的接收者 12 Command command = new ConcreteCommand(receiver); 13 //创建请求者,把命令对象设置进去 14 Invoker invoker = new Invoker(command); 15 //执行方法 16 invoker.action(); 17 } 18 }
现在我们在具体点讲一个事例,此处是开发过程中遇到的一个例子,在过去的开发中,曾经有一个界面,上面有着多处第三方登录,比如QQ登录,新浪微博登录,微信登录…
接收者角色类
1 public class Receiver 2 { 3 public void tencentLogin(){ 4 System.out.println("QQ登录"); 5 } 6 7 public void weChatLogin(){ 8 System.out.println("weChat登录"); 9 } 10 11 public void sinaLogin(){ 12 System.out.println("sina登录"); 13 } 14 }
抽象命令角色类
1 public interface Command 2 { 3 void execute(); 4 }
具体命令角色类
1 public class SinaCommand implements Command 2 { 3 private Receiver receiver; 4 5 public SinaCommand(Receiver receiver) 6 { 7 this.receiver = receiver; 8 } 9 10 public void execute() { 11 receiver.sinaLogin(); 12 } 13 }
1 public class TencentCommand implements Command 2 { 3 private Receiver receiver; 4 5 public TencentCommand(Receiver receiver) 6 { 7 this.receiver = receiver; 8 } 9 10 public void execute() { 11 receiver.tencentLogin(); 12 } 13 }
1 public class WeChatCommand implements Command 2 { 3 private Receiver receiver; 4 5 public WeChatCommand(Receiver receiver) 6 { 7 this.receiver = receiver; 8 } 9 10 public void execute() { 11 receiver.weChatLogin(); 12 } 13 }
请求者角色类
1 public class Invoker 2 { 3 //开发过程中没有此属性,此处作为示例,用来便利和撤销操作 4 private static List<Command> list = new ArrayList<Command>(); 5 6 public Invoker(Command command) 7 { 8 list.add(command); 9 } 10 11 public void action(Command command){ 12 command.execute(); 13 } 14 15 public void removeAction(Command command){ 16 if(list.contains(command)){ 17 System.out.println(command.getClass().getName()+"被移除"); 18 list.remove(command); 19 } 20 } 21 22 public void allAction(){ 23 if(list.size()>0){ 24 for (Command mCommand : list) 25 { 26 mCommand.execute(); 27 } 28 } 29 } 30 }
客户端角色类
1 public class Client 2 { 3 4 /** 5 * created by zm on 16-05-22 6 */ 7 public static void main(String[] args) { 8 // TODO Auto-generated method stub 9 //创建接收者 10 Receiver receiver = new Receiver(); 11 //创建命令对象,设定它的接收者 12 Command tencentCommand = new TencentCommand(receiver); 13 Command weChatCommand = new WeChatCommand(receiver); 14 Command sinaCommand = new SinaCommand(receiver); 15 //创建请求者,把命令对象设置进去 16 Invoker invoker = new Invoker(tencentCommand); 17 invoker = new Invoker(weChatCommand); 18 invoker = new Invoker(sinaCommand); 19 //执行方法 20 invoker.allAction(); 21 System.out.println("................."); 22 invoker.removeAction(tencentCommand); 23 System.out.println("................."); 24 invoker.allAction(); 25 } 26 }
执行后的结果如下:
QQ登录
weChat登录
sina登录
……………..
com.zm.zero.TencentCommand被移除
……………..
weChat登录
sina登录
总结:敏捷开发告诉我们,不要为了添加基于猜测的、实际不需要的功能,如果不清楚一个系统是否需要命令模式,一般就不要着急去实现它,事实上,在需要的时候通过重构实现这个模式并不困难,只有在真正需要撤销/恢复操作等功能时,把原来的代码重构为命令模式才有意义。
参考文献:《Java与模式》、《大话设计模式》《head first 设计模式》
标签:
原文地址:http://www.cnblogs.com/zero-million/p/5518317.html