`
dreamstone
  • 浏览: 283537 次
  • 来自: ...
文章分类
社区版块
存档分类

Java中的模式 --- 命令模式的(实现,功能,使用场合)及如何配合其它模式使用命令模式

阅读更多
一,命令模式的实现:
命令模式里边一般都有以下几个角色:客户端,请求者,命令接口,命令实现,接受者,
下边是简单命令模式的实现代码实现:
 1public class Client{
 2    public static void main(String[] args){
 3        Receiver receiver = new Receiver();
 4        Command commandOne = new ConcreteCommandOne(receiver);
 5        Command commandTwo = new ConcreteCommandTwo(receiver);
 6        Invoker invoker = new Invoker(commandOne,commandTwo);
 7        invoker.actionOne();
 8        invoker.actionTwo();
 9    }

10}

11public class Invoker{
12    private Command commandOne;
13    private Command commandTwo;
14    public Invoker(Command commandOne,Command commandTwo){
15        this.commandOne = commandOne;
16        this.commandTwo = commandTwo;
17    }

18    public void actionOne(){
19        commandOne.execute();
20    }

21    public void actionTwo(){
22        commandTwo.execute();
23    }

24}

25public interface Command{
26    void execute();
27}

28public class ConcreteCommandOne implements Command{
29    private Receiver receiver
30    public ConcreteCommandOne(Receiver receiver){
31        this.receiver = receiver;
32    }

33    public void execute(){
34        receiver.actionOne();
35    }

36}

37public class ConcreteCommandTwo implements Command{
38    private Receiver receiver
39    public ConcreteCommandTwo(Receiver receiver){
40        this.receiver = receiver;
41    }

42    public void execute(){
43        receiver.actionTwo();
44    }

45}

46public class Receiver{
47    public Receiver(){
48        //
49    }

50    public void actionOne(){
51        System.out.println("ActionOne has been taken.");
52    }

53    public void actionTwo(){
54        System.out.println("ActionTwo has been taken.");
55    }

56}

二,命令模式的功能,好处,或者说为什么使用命令模式?
上边的代码是否看起来很傻呢,本来可以这样简单实现的:
 1public class Client{
 2    public static void main(String[] args){
 3        Receiver receiver = new Receiver();
 4        receiver.actionOne();
 5        receiver.actionTwo();
 6    }

 7}

 8public class Receiver{
 9    public Receiver(){
10        //
11    }

12    public void actionOne(){
13        System.out.println("ActionOne has been taken.");
14    }

15    public void actionTwo(){
16        System.out.println("ActionTwo has been taken.");
17    }

18}


看多简洁,如果是像上边如此简单的需求,这个才应该是我们的选择,但是有些情况下这样的写法不能解决的,
或者说解决起来不好,所以引入命令模式.
(1)我们须要Client和Receiver同时开发,而且在开发过程中分别须要不停重购,改名
(2)如果我们要求Redo ,Undo等功能
(3)我们须要命令不按照调用执行,而是按照执行时的情况排序,执行
(4)开发后期,我们发现必须要log哪些方法执行了,如何在尽量少更改代码的情况下实现.并且渐少重复代码
(5)在上边的情况下,我们的接受者有很多,不止一个
解决办法:
情况一,我们可以定义一个接口,让Receiver实现这个接口,Client按照接口调用。
情况二,我们可以让Receiver记住一些状态,例如执行前的自己的状态,用来undo,但自己记录自己的状态
 实现起来比较混乱,一般都是一个累记录另一个类的状态.
情况三,很难实现
情况四,,我们须要在每个Action,前后加上log
情况五,相对好实现,但是再加上这个,是否感觉最终的实现很混乱呢
好,我们再来看看命令模式,在命令模式中,我们增加一些过渡的类,这些类就是上边的命名接口和命令实现,
这样就很好的解决了情况一,情况二。我们再加入一个Invoker,这样情况三和情况四就比较好解决了。

如下加入Log和排序后的Invoker

 1public class Invoker{
 2    private List cmdList = new ArrayList();
 3    public Invoker(){
 4    }

 5    public add(Command command){
 6        cmdList.add(command);
 7    }

 8    public remove(Command command){
 9        cmdList.remove(command);
10    }

11    public void action(){
12        Command cmd;
13        while((cmd =getCmd()) != null){
14            log("begin"+cmd.getName());
15            cmd.execute();
16            log("end"+cmd.getName());        
17        }

18    }

19    public Command getCmd(){
20        //按照自定义优先级,排序取出cmd
21    }

22}

23public class Client{
24    public static void main(String[] args){
25        Receiver receiver = new Receiver();
26        Command commandOne = new ConcreteCommandOne(receiver);
27        Command commandTwo = new ConcreteCommandTwo(receiver);
28        Invoker invoker = new Invoker();
29        invoker.add(commandOne);
30        invoker.add(commandTwo);
31        iinvoker.action();
32    }

33}


三,命令模式与其它模式的配合使用:
1,看上边的Invoker的实现是否很像代理模式呢,Invoker的这种实现其实就是一种代理模式。

2,需求:有个固定命令组合会多次被执行
   解决:加入合成模式,实现方法如下,定义一个宏命令类:

 1public class MacroCommand implements Command{
 2    private List cmdList = new ArrayList();
 3
分享到:
评论

相关推荐

    二十三种设计模式【PDF版】

    GoF 的《设计模式》是所有面向对象语言(C++ Java C#)的基础,只不过不同的语言将之实现得更方便地使用。 GOF 的设计模式是一座"桥" 就 Java 语言体系来说,GOF 的设计模式是 Java 基础知识和 J2EE 框架知识之间一...

    java 面试题 总结

    知道其行为的其它类可以在类中实现这些方法。 接口(interface)是抽象类的变体。在接口中,所有方法都是抽象的。多继承性可通过实现这样的接口而获得。接口中的所有方法都是抽象的,没有一个有程序体。接口只可以...

    超级有影响力霸气的Java面试题大全文档

    知道其行为的其它类可以在类中实现这些方法。  接口(interface)是抽象类的变体。在接口中,所有方法都是抽象的。多继承性可通过实现这样的接口而获得。接口中的所有方法都是抽象的,没有一个有程序体。接口只可以...

    OCPOCA认证考试指南全册:Oracle Database 11g(1Z0-051,1Z0-052,1Z0-053)--详细书签版(第2/2部分)

    4.2.4 使用共享服务器的场合 132 4.3 本章知识点回顾 134 4.4 自测题 135 4.5 自测题答案 137 第5章 Oracle存储结构 139 5.1 了解表空间和数据文件 140 5.1.1 Oracle数据存储模型 140 5.1.2 段、区间、块和...

    OCPOCA认证考试指南全册:Oracle Database 11g(1Z0-051,1Z0-052,1Z0-053)--详细书签版(第1/2部分)

    4.2.4 使用共享服务器的场合 132 4.3 本章知识点回顾 134 4.4 自测题 135 4.5 自测题答案 137 第5章 Oracle存储结构 139 5.1 了解表空间和数据文件 140 5.1.1 Oracle数据存储模型 140 5.1.2 段、区间、块和...

    Python编程入门经典

    17.7 在C代码中使用Python 对象 342 17.8 本章小结 345 17.9 习题 346 第18章 数值编程 347 18.1 Python语言中的数值 347 18.1.1 整数 348 18.1.2 长整数 348 18.1.3 浮点数 349 18.1.4 格式化数值 350 18.1.5 作为...

    oracle学习文档 笔记 全面 深刻 详细 通俗易懂 doc word格式 清晰 连接字符串

    功能:数据库如何使用物理空间 组成:表空间、段、区、块的组成层次 六、 oracle安装、卸载和启动  硬件要求 物理内存:1GB 可用物理内存:50M 交换空间大小:3.25GB 硬盘空间:10GB  安装 1. 安装程序成功...

    深入云计算 MongoDB管理与开发实战详解pdf.part1

    1.5.7 使用场合 1.6 本章小结 第2章 MongoDB基本原理与安装 2.1 数据库结构 2.2 文档 2.3 集合 2.3.1 集合的无模式 2.3.2 集合的命名 2.4 MongoDB数据类型 2.4.1 基本数据类型 2.4.2 数字...

    深入云计算 MongoDB管理与开发实战详解pdf.part2

    1.5.7 使用场合 1.6 本章小结 第2章 MongoDB基本原理与安装 2.1 数据库结构 2.2 文档 2.3 集合 2.3.1 集合的无模式 2.3.2 集合的命名 2.4 MongoDB数据类型 2.4.1 基本数据类型 2.4.2 数字...

Global site tag (gtag.js) - Google Analytics