1、什么是命令模式?
命令模式(Commond Pattern):将来自客户端的请求封装为一个对象,无需了解这个请求激活的动作或有关接受这个请求的处理细节。命令模式的根本目的在于将“请求者”与“实现者”之间解耦。
其实命令模式和其他许多设计模式一样,就是在请求者和实现者中间加一个中间人的角色,来达到解除耦合的目的。通过对中间人的特殊设置,从而形成不同的设计模式,命令模式也不例外。命令模式正是通过一个中间的命令者角色完成请求与实现之间的解耦。
2、命令模式的类图:
命令模式分为三部分,调用者、接收者和命令类,其实质是在命令发出者和命令接受者之间增加第三方来实现解耦,下面来使用实例来说明。
3、命令模式实例
需求:使用命令模式完成邮局案例,需要一个发件人、邮局、收件人三种实体对象。发件人投递信件给邮局,邮局需要做的是将信件发给收件人,自始至终,我们都没有让发件人和收件人进行直接通信,也就是说,命令的调用者和接收者是没有联系的,完全通过邮局这个中间人来联系。
案例类图:
首先创建一个“IReceiver”收件人接口,其中只有一个读取信件的readMail方法:
<span style="font-size:18px;"> /* * 功能:命令模式,接收者 * 信件接收者 */ public interface IReceiver { public void readMail(String message); }</span>
<span style="font-size:18px;"> /* * 功能:接收者实现类 */ public class ReceiverImp implements IReceiver { @Override public void readMail(String message) { System.out.println("收件人读取信息:"+message); } }</span>
<span style="font-size:18px;"> /* * 功能:邮局接口,即命令接口 * */ public interface IPost { public void sendMail(String message); }</span>
<span style="font-size:18px;"> /* * 功能:邮局接口实现类 */ public class IPostImp implements IPost { // 保持对收件人的引用 private final IReceiver receiver; //通过构造方法传入 public IPostImp(IReceiver receiver){ this.receiver = receiver; } //具体发送功能 @Override public void sendMail(String message) { System.out.println("信息已经发送给收件人!"); receiver.readMail(message); } }</span>
<span style="font-size:18px;"> /* * 功能:发送者,即命令调用者 */ public class Invoker { //保留邮局引用 private IPost ipost; //设置邮局对象实例 public void setPost(IPost ipost){ this.ipost=ipost; } //发件人发送信息 public void postMail(String message){ System.out.println("发信人开始投递邮件给邮局。。。"); ipost.sendMail(message); } }</span>
<span style="font-size:18px;"> /* * 功能:测试类 */ public class Test { public static void main(String[] args) { Invoker in = new Invoker(); ReceiverImp receiver = new ReceiverImp(); IPostImp post = new IPostImp(receiver); in.setPost(post); in.postMail("我来了!"); } }</span>
总结:命令模式中,精髓就是请求的启动者发送命令请求给具体命令,由具体命令负责发送命令消息给命令的接收者,具体命令就是模式模式中的中间人角色。
命令模式的适用场合:
抽象出待执行的动作以参数化某对象。类似于过程设计中的回调机制,而命令模式正式回调机制的一个面向对象的替代品;
在不同的时刻指定、排列和执行请求;
需要支持可撤销的操作;
需要支持修改日志功能。这样当系统崩溃时,这些修改可以被重做一遍;
需要支持事务系统。