15-邮局:命令模式
15.1 邮局寄信
本章我们以通过邮局寄信的例子来学习命令模式。
15.2 模式定义
命令模式(Command Pattern),将来自客户端的请求封装成一个对象,无须了解这个请求激活的动作或者有关接受这个请求的处理细节。命令模式的根本目的在于将“请求者”与“实现者”之间解耦。其实命令模式与很多其它设计模式一样,就是在请求者和实现者之间增加一个中间人的角色,来达到解除耦合的目的。通过对中间角色的特殊设置,从而形成不同的设计模式,命令模式也不例外。
15.3 模式实现
15.3.1 创建消息接收者接口——IReceiver
package com.demo.receiver; /** * Created by lsq on 2018/3/27. * 信件接收者接口 */ public interface IReceiver { /** * 收件人收到信件读取 * @param message */ public void readMail(String message); }
15.3.2 创建消息接收者类——Receiver
package com.demo.receiver; /** * Created by lsq on 2018/3/27. * 信件接收者 */ public class Receiver implements IReceiver{ /** * 收件人读取信件 * @param message */ public void readMail(String message){ System.out.println("收件人读取信件:"+message); } }
15.3.3 创建中间角色邮局
1. 邮局接口——IPost
package com.demo.command; /** * Created by lsq on 2018/3/27. * 邮局接口 */ public interface IPost { /** * 邮局发送信件 * @param message */ public void sendMail(String message); }
2. 邮局实现——Post
package com.demo.command; import com.demo.receiver.IReceiver; /** * Created by lsq on 2018/3/27. * 邮局实现类 */ public class Post implements IPost{ //收信人对象实例 private final IReceiver receiver; /** * 构造方法传入收信人对象实例 * @param receiver */ public Post(IReceiver receiver){ this.receiver = receiver; } /** * 邮局发送信件 * @param message */ @Override public void sendMail(String message) { System.out.println("邮局将信件发送给收信人……"); //邮局发送信件给收信人 this.receiver.readMail(message); } }
15.3.4 创建消息发送者
package com.demo.invoker; import com.demo.command.IPost; /** * Created by lsq on 2018/3/27. * 发件人 */ public class Invoker { //邮局作为私有属性 private IPost post; /** * 通过set方法设置邮局对象实例 * @param post */ public void setPost(IPost post){ this.post = post; } public void postMail(String message){ System.out.println("发件人投递信件给邮局……"); this.post.sendMail(message); } }
15.3.5 客户端程序
package com.demo; import com.demo.command.IPost; import com.demo.command.Post; import com.demo.invoker.Invoker; import com.demo.receiver.IReceiver; import com.demo.receiver.Receiver; /** * Created by lsq on 2018/3/27. * 应用程序 */ public class Client { public static void main(String[] args) { //创建一个收件人对象实例 IReceiver receiver = new Receiver(); //创建一个邮局对象实例,传入收件人对象实例 IPost post = new Post(receiver); //创建一个发件人对象实例,传入邮局对象实例 Invoker invoker = new Invoker(); invoker.setPost(post); //发件人开始发送信息 invoker.postMail("你好!好久不见,最近还好吗?"); } }
运行结果:
15.4 使用场合
1)抽象出待执行的动作以参数化某对象。类似于过程设计中的回调机制,而命令模式正是回调机制的一个面向对象的替代品。
2)在不同的时刻指定、排列和执行请求。
3)需要支持可撤销的操作。
4)需要支持修改日志功能。这样当系统崩溃时,这些修改可以被重新做一遍。
5)需要支持事务系统。