COMMAND 模式

command模式非常简单,简单到你无法想象的地方。

  1. public interface Command {
  2. void execute();
  3. }

这就是一个command模式的样子。也许你会觉得,这有点多此一举吗。但是当你使用他的时候,command模式就会闪现光华。

这样一个场景:经理张三叫leader王二去开发一个项目, 王二就安排李四 去开发这个功能A。 李四何时执行,怎么执行就是他自己的事情了。

 UML图如上所示:
代码如下:
  1. public interface CommandInterface {
  2. void execute();
  3. }
  1. public class ContractCommand implements CommandInterface {
  2. Member member;
  3.  
  4. public ContractCommand(Member member) {
  5. this.member = member;
  6. }
  7.  
  8. @Override
  9. public void execute() {
  10. member.action();
  11. }
  12. }
  1. public class Member {
  2. public void action()
  3. {
  4. TraceLog.i();
  5. }
  6. }

Leader,获取命令,然后执行命令。

  1. public class Leader {
  2. CommandInterface commandInterface;
  3.  
  4. public void setCommandInterface(CommandInterface commandInterface) {
  5. this.commandInterface = commandInterface;
  6. }
  7.  
  8. public void executeCommand()
  9. {
  10. commandInterface.execute();
  11. }
  12. }
  1. public class Manager {
  2. public static void main()
  3. {
  4. Member m = new Member();
  5. CommandInterface c = new ContractCommand(m);
  6. Leader wang2 = new Leader();
  7.  
  8. wang2.setCommandInterface(c);
  9. wang2.executeCommand();
  10. }
  11. }

manager创建运行的平台。

这样命令模式就开启了。

Active Object

Active Object 模式

一开始蛮难理解这个模式的目的,而且GOF的23中经典模式里也没有这个模式。

  1. /**
  2. * @author deman.lu
  3. * @version on 2016-06-02 14:45
  4. */
  5. public class ActiveObjectEngine {
  6. List<CommandInterface> itsCommands = new ArrayList();
  7.  
  8. /*need to running in main thread, should check with synchronized*/
  9. public void addCommand(CommandInterface aCommand)
  10. {
  11. itsCommands.add(aCommand);
  12. }
  13.  
  14. public void run()
  15. {
  16. /*should running in background*/
  17. while (itsCommands.size() > 0)
  18. {
  19. CommandInterface c = itsCommands.get(0);
  20. itsCommands.remove(0);
  21. c.execute();
  22. }
  23. }
  24. }

这个就是ActiveObject的engine,2个函数。一个是把一条command添加到表里面。

另一个是一个循环,处理问题。仔细思考,这就是消费者,和生产者问题的变种。

but这里没有线程block的地方。先看完全部代码:

  1. public class SleepCommand implements CommandInterface {
  2. @Override
  3. public void execute() {
  4. Date currentTime = new Date();
  5. if (!started) {
  6. started = true;
  7. this.startTime = currentTime;
  8. this.engine.addCommand(this);
  9. } else {
  10. long elapsedTime = currentTime.getTime() - startTime.getTime();
  11. if (elapsedTime < SleepTime) {
  12. this.engine.addCommand(this);
  13. } else {
  14. this.engine.addCommand(this.wakeupCommand);
  15. }
  16. }
  17. }
  18.  
  19. private CommandInterface wakeupCommand = null;
  20. private ActiveObjectEngine engine = null;
  21. private long SleepTime = 0;
  22. private Date startTime;
  23. private boolean started = false;
  24.  
  25. public SleepCommand(long milliSeconds, ActiveObjectEngine e,
  26. CommandInterface wakeupCommand) {
  27. this.SleepTime = milliSeconds;
  28. this.engine = e;
  29. this.wakeupCommand = wakeupCommand;
  30. }
  31.  
  32. }
  1. public class DelayedTyper implements CommandInterface {
  2. private long itsDelay;
  3. private char itsChar;
  4. private static boolean stop = false;
  5. static String printStr = "";
  6. private static ActiveObjectEngine engin =
  7. new ActiveObjectEngine();
  8.  
  9. static class StopCommand implements CommandInterface
  10. {
  11. @Override
  12. public void execute() {
  13. DelayedTyper.stop = true;
  14. }
  15. }
  16.  
  17. public static void Main()
  18. {
  19. engin.addCommand(new DelayedTyper(100, 'A'));
  20. engin.addCommand(new DelayedTyper(300, 'B'));
  21. engin.addCommand(new DelayedTyper(500, 'C'));
  22. engin.addCommand(new DelayedTyper(700, 'D'));
  23.  
  24. CommandInterface stopCommand = new StopCommand();
  25. engin.addCommand(new SleepCommand(2000, engin, stopCommand));
  26. engin.run();
  27. TraceLog.i(printStr);
  28. }
  29.  
  30. public DelayedTyper(long delay, char c)
  31. {
  32. this.itsDelay = delay;
  33. this.itsChar = c;
  34. }
  35.  
  36. @Override
  37. public void execute()
  38. {
  39. printStr +=itsChar;
  40. if (!stop)
  41. {
  42. DelayAndRepeat();
  43. }
  44. }
  45.  
  46. private void DelayAndRepeat()
  47. {
  48. engin.addCommand(new SleepCommand(itsDelay, engin, this));
  49. }
  50. }

结果如下:

ABCDAAABACABAADAABCAAABAADABCAAABAACDB

当DelayedTyper没有到执行的时间点的时候,启动SleepCommand。

这个很关键,

  1. if (elapsedTime < SleepTime) {
  2. this.engine.addCommand(this);
  3. } else {
  4. this.engine.addCommand(this.wakeupCommand);
  5. }

如果时间没到,就把自己加入到队列最后,等待下次执行。(此处没有用常见的线程block技术)

时间到了,就把wakeupCommand加入执行队列。

这里还有个关键是,没有stopcommand,命令会一直循环执行。

参考:

《敏捷软件开发》 Robert C. Martin

敏捷软件开发(3)---COMMAND 模式 & Active Object 模式的更多相关文章

  1. Java多线程编程模式实战指南:Active Object模式(下)

    Active Object模式的评价与实现考量 Active Object模式通过将方法的调用与执行分离,实现了异步编程.有利于提高并发性,从而提高系统的吞吐率. Active Object模式还有个 ...

  2. java Active Object模式(下)

    Active Object模式的评价与实现考量 Active Object模式通过将方法的调用与执行分离,实现了异步编程.有利于提高并发性,从而提高系统的吞吐率. Active Object模式还有个 ...

  3. Java多线程编程模式实战指南一:Active Object模式(下)

    Active Object模式的评价与实现考量 Active Object模式通过将方法的调用与执行分离,实现了异步编程.有利于提高并发性,从而提高系统的吞吐率. Active Object模式还有个 ...

  4. Java多线程编程模式实战指南(一):Active Object模式--转载

    本文由黄文海首次发布在infoq中文站上:http://www.infoq.com/cn/articles/Java-multithreaded-programming-mode-active-obj ...

  5. 敏捷软件开发(4)--- TEMPLATE METHOD & STRATEGY 模式

    1.TEMPLATE METHOD 泛型,也就是这个模式,是可以基于泛型的. 我们往往会有一些算法,比如排序算法.它的算法部分,我可以把它放在一个基类里面,这样具体类型的比较可以放在子类里面. 看如下 ...

  6. 敏捷软件开发:原则、模式与实践——第12章 ISP:接口隔离原则

    第12章 ISP:接口隔离原则 不应该强迫客户程序依赖并未使用的方法. 这个原则用来处理“胖”接口所存在的缺点.如果类的接口不是内敛的,就表示该类具有“胖”接口.换句话说,类的“胖”接口可以分解成多组 ...

  7. 敏捷软件开发:原则、模式与实践——第13章 写给C#程序员的UML概述

    第13章 写给C#程序员的UML概述 UML包含3类主要的图示.静态图(static diagram)描述了类.对象.数据结构以及它们之间的关系,藉此表现出了软件元素间那些不变的逻辑结构.动态图(dy ...

  8. 敏捷软件开发:原则、模式与实践——第9章 OCP:开放-封闭原则

    第9章 OCP:开放-封闭原则 软件实体(类.模块.函数等)应该是可以扩展的,但是不可修改. 9.1 OCP概述 遵循开放-封闭原则设计出的模块具有两个主要特征: (1)对于扩展是开放的(open f ...

  9. 敏捷软件开发(1)--- STATE 模式

    如果状态在运行过程中,不停的切换和改变,我们怎么办? 状态的迁移是我们生活和工程中非常普遍的一个概念.于是在数学上有一种理论来分析和解决这个问题. 有限状态机理论是一个非常成熟的理论,所有动作和流程的 ...

随机推荐

  1. 15款提高工作效率的 Web 项目管理工具

    在今天的快节奏的商业世界里,能够通过计划.组织.和管理资源池以及评估开发资源的模式来管理一个项目,是一个很艰巨的任务. 有很多现成的项目管理软件来帮助减轻项目管理的负担,并且他们几乎覆盖了所有类型的业 ...

  2. Android 学习笔记之Volley(八)实现网络图片的数据加载

    PS:最后一篇关于Volley框架的博客... 学习内容: 1.使用ImageRequest.java实现网络图片加载 2.使用ImageLoader.java实现网络图片加载 3.使用NetWork ...

  3. Android学习笔记之布局技巧以及布局中的细节介绍....

    PS:休息两天,放一放手上的东西,做做总结... 学习内容: 1.Android中LinearLayout布局技巧... 2.layout中drawable属性的区别...   先简单的介绍一下dra ...

  4. 哀悼我的第一次"创业"经历

    下周考完最后一科,大学四年时光基本上算是落下帷幕,剩下的就只是整整毕业设计了.如果按照正常的节奏,这个学期应该能够搞完毕业设计的2/3,但无奈还在广州的一家公司里面实习,没有多少时间弄,得拖到3月了. ...

  5. What Is Seedwork

    最近研究DDD,发现很多DDD的例子都有一个Seedwork的项目.从名字我没办法推断是什么作用,看代码里面是一些公共的接口跟基类.google了一会基本都是英文资料.发现两篇大作.下面是摘要: 1. ...

  6. 2015年百度之星初赛(1) --- A 超级赛亚ACMer

    超级赛亚ACMer Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Problem D ...

  7. C#设计模式——观察者模式(Observer Pattern)

    一.概述在软件设计工作中会存在对象之间的依赖关系,当某一对象发生变化时,所有依赖它的对象都需要得到通知.如果设计的不好,很容易造成对象之间的耦合度太高,难以应对变化.使用观察者模式可以降低对象之间的依 ...

  8. ASP.NET MVC5 网站开发实践

    http://www.cnblogs.com/mzwhj/p/3538108.html

  9. 重新想象 Windows 8 Store Apps (36) - 通知: Tile 详解

    [源码下载] 重新想象 Windows 8 Store Apps (36) - 通知: Tile 详解 作者:webabcd 介绍重新想象 Windows 8 Store Apps 之 通知 Tile ...

  10. mysql防止重复插入记录方法总结

    mysql防止重复插入记录方法总结 防止mysql重复插入记录的方法有很多种,常用的是ignore,Replace,ON DUPLICATE KEY UPDATE,当然我们也可以在php中加以判断了. ...