命令模式(Command Pattern)
命令模式将一个请求封装为一个对象,从而使用户可用不同的请求对客户进行参数化;将请求排队或记录请求日志,支持可撤销的操作。命令模式的根本在于将“请求者”与“实现者”之间解耦。
大类属于行为型模式。
介绍
意图:将一个请求封装成一个对象,从而使您可以用不同的请求对客户进行参数化。
使用场景:
1. 抽象出待执行的动作以参数化某对象。类似于过程设计中的回调机制,而命令模式正是回调机制的一个面向对象的替代品。
2. 在不同的时刻指定、排列和执行请求。
3. 需要支持可撤销的操作。
4. 需要支持修改日志功能。这样当系统崩溃时,这些修改可以被重做一遍。
5. 需要支持事务系统。
优点:1. 降低了系统耦合度。2. 新的命令可以很容易添加到系统中去。
缺点:使用命令模式可能会导致某些系统有过多的具体命令类。
注意事项:系统需要支持命令的撤销(Undo)操作和恢复(Redo)操作,也可以考虑使用命令模式,见命令模式的扩展。
实现
我们模拟一个传统书信通信的过程,在这个场景中,有三种角色,发信人,收信人,邮局。通信过程中,发信人将信件投递给邮局,然后邮局负责将信件投递到收信人手里边。投递给谁,怎么投递这个逻辑都是邮局处理的。在该场景中,通过邮局,将发件人和收信人进行了很好的解耦,发件人和收信人都不关心这个中间过程是如何实现,只需要跟邮局之间有一个联系即可。
步骤 1
创建一个用于接收信件的接口。先创建收信件的接口是因为在实际场景中,收信人必定是最先存在的;之所以创建接口而不创建实体对象是在设计模式中要面向抽象编程,而不是依赖具体实现。
IReceiver.java
package com.study.command;
public interface IReceiver {
void readMail(String message);
}
创建一个邮局接口。
IMailPost.java
package com.study.command;
/**
* @author admin
* @version 1.0
* @created 02-十一月-2016 15:46:22
*/
public interface IMailPost {
public void sendMail(String message);
}//end IMailPost
创建一个发信人接口。
ISender.java
package com.study.command;
public interface ISender {
void postMail(String message);
void setPost(IMailPost post);
}
步骤 2
实现上述接口。
接收人
Receiver.java
package com.study.command;
/**
* @author admin
* @version 1.0
* @created 02-十一月-2016 15:46:25
*/
public class Receiver implements IReceiver{
/**
*
* @param message
*/
public void readMail(String message){
System.out.println("read message:" + message);
}
}//end Receiver
邮局
MailPostImpl.java
package com.study.command;
/**
* 邮局
* @author admin
* @version 1.0
* @created 02-十一月-2016 15:46:24
*/
public class MailPostImpl implements IMailPost {
private final IReceiver receiver;
/**
*
* @param receiver
*/
public MailPostImpl(IReceiver receiver) {
this.receiver = receiver;
}
/**
*
* @param message
*/
public void sendMail(String message) {
System.out.println("post to reader。。。。");
this.receiver.readMail(message);
}
}
发信人
Sender.java
package com.study.command;
/**
* 邮件发送人
* @author admin
* @version 1.0
* @created 02-十一月-2016 15:46:27
*/
public class Sender implements ISender{
private IMailPost post;
/**
*
* @param message
*/
public void postMail(String message){
System.out.println("post mail。。。");
this.post.sendMail(message);
}
/**
*
* @param post
*/
public void setPost(IMailPost post){
this.post = post;
}
}//end Sender
步骤 3
测试实现。
Test.java
package com.study.command;
public class Test {
public static void main(String[] args) {
IReceiver receiver = new Receiver();
ISender sender = new Sender();
IMailPost post = new MailPostImpl(receiver);
sender.setPost(post);
sender.postMail("hello friends");
}
}
验证输出。
post mail。。。
post to reader。。。。
read message:hello friends