Command??

把方法的调用用一个类的实例来承载,要管理工作的历史记录,创建这些方法执行的命令的集合,只需管理这些实例的集合即可,而且还可以随时再次执行过去的命令,或是将多个过去的命令整合为一个新命令并执行。称之为Command设计模式

  • 那里合适使用:

    Command有时也被称为事件(event)。它与“事件驱动编程”中的“事件”是一样的意思。当发生点击鼠标、按下键盘按键等事件时,我们可以先将这些事件作成实例,然后按照发生顺序放入队列中。接着,再依次去处理它们。在GUI(graphical user interface)编程中,经常需要与“事件”打交道。即为在有多个命令,并且这些命令有一定的逻辑顺序,且可能需要保存的这些命令的数据,那么可以使用Command设计模式。

理清职责

  • 实现简单的画图板:

    |包=名字说明

    |command |command表示“命令”的接口

    |command |Macrocommand |表示“由多条命令整合成的命令”的类

    |drawer |Drawcommand |表示“绘制一个点的命令”的类

    |drawer |Drawable|表示“绘制对象”的接口

    |drawer |Drawcanvas实现“绘制对象”的类

    |无名|MainT测试程序行为的类

  • 扩展命令:

    只需要实现command,并且关联操作的属性类即可


  1. ColorCommand implements Command {
  2. private xxxAction xxxx
  3. private XxxArgs xxxx;
  4. xxxxAction....
  5. }
  • 相关设计模式
  1. ◆Composite模式(第11章)有时会使用Composite模式实现宏命令(macrocommand)。
  2. ◆Memento模式(第18章)有时会使用Memento模式来保存Command角色的历史记录。
  3. ◆Protype模式(第6章)有时会使用Protype模式复制发生的事件(生成的命令)。

UML

时序图:

Code

  • Comamnd 包

  1. public interface Command {
  2. void execute();
  3. }
  4. public class MacroCommand implements Command {
  5. // 命令集合 便于执行UNdo操作
  6. private Stack commands=new Stack();
  7. // 执行stack中所有命令
  8. @Override
  9. public void execute() {
  10. Iterator it = commands.iterator();
  11. while (it.hasNext()){
  12. Command o = ((Command) it.next());
  13. o.execute();
  14. }
  15. }
  16. public void append(Command command){
  17. if (command!=null){
  18. commands.add(command);
  19. }
  20. }
  21. // 移除末尾命令
  22. public void undo(){
  23. if(!commands.empty()){
  24. commands.pop();
  25. }
  26. }
  27. // 移除所有命令
  28. public void clear(){
  29. commands.clear();
  30. }
  31. }
  • Drawer 包

  1. public interface Drawable {
  2. void draw(int x,int y);
  3. void setColor(Color color);
  4. }
  5. public class ColorCommand implements Command {
  6. private Drawable drawable;
  7. private Color color;
  8. public ColorCommand(Drawable drawable, Color color) {
  9. this.drawable = drawable;
  10. this.color = color;
  11. }
  12. @Override
  13. public void execute() {
  14. drawable.setColor(color);
  15. }
  16. }
  17. public class DrawCommand implements Command {
  18. // 绘制对象
  19. private Drawable drawable;
  20. // 绘制位置
  21. private Point point;
  22. public DrawCommand(Drawable drawable, Point point) {
  23. this.drawable = drawable;
  24. this.point = point;
  25. }
  26. @Override
  27. public void execute() {
  28. drawable.draw(point.x,point.y);
  29. }
  30. }
  31. public class DrawCanvas extends Canvas implements Drawable {
  32. // defulat 颜色
  33. private Color color=Color.red;
  34. private int radius=6;
  35. private MacroCommand history;
  36. private Graphics2D graphics;
  37. public DrawCanvas(int width,int height,MacroCommand history) {
  38. setSize(width,height);
  39. setBackground(Color.white);
  40. this.history=history;
  41. }
  42. // 重新绘制
  43. @Override
  44. public void paint(Graphics graphics){
  45. history.execute();
  46. }
  47. /**
  48. * 这里的实现的画点轨迹依据本身物理操作的手势的速度定型的,
  49. * 即为:手快 画点 手慢 画线
  50. * @param x
  51. * @param y
  52. */
  53. @Override
  54. public void draw(int x, int y) {
  55. graphics = (Graphics2D) getGraphics();
  56. graphics.fillOval(x-radius,y-radius,radius*2,radius*2);
  57. //graphics.drawOval(x-radius,y-radius,radius*2,radius*2);
  58. }
  59. @Override
  60. public void setColor(Color color) {
  61. graphics = (Graphics2D) getGraphics();
  62. graphics.setColor(color);
  63. }
  64. }
  • MainT
  1. public class MainT extends JFrame implements ActionListener, MouseMotionListener, WindowListener {
  2. private MacroCommand history=new MacroCommand();
  3. private DrawCanvas canvas=new DrawCanvas(500,500,history);
  4. private JButton clearbtn=new JButton("clear");
  5. private JButton undobtn=new JButton("撤销");
  6. public MainT(String title) {
  7. super(title);
  8. setLocationRelativeTo(getComponentAt(-500,-500));
  9. this.addWindowListener(this);
  10. canvas.addMouseMotionListener(this);
  11. clearbtn.addActionListener(this);
  12. undobtn.addActionListener(this);
  13. Box btnbox=new Box(BoxLayout.X_AXIS);
  14. btnbox.add(clearbtn);
  15. btnbox.add(undobtn);
  16. Box mainbox=new Box(BoxLayout.Y_AXIS);
  17. mainbox.add(canvas);
  18. mainbox.add(btnbox);
  19. getContentPane().add(mainbox);
  20. pack();
  21. show();
  22. }
  23. public static void main(String[] args) {
  24. new MainT("mspaint");
  25. }
  26. @Override
  27. public void actionPerformed(ActionEvent e) {
  28. if(e.getSource()==clearbtn){
  29. history.clear();
  30. canvas.repaint();
  31. }else if(e.getSource()==undobtn){
  32. history.undo();
  33. canvas.repaint();
  34. }
  35. }
  36. @Override
  37. public void mouseDragged(MouseEvent e) {
  38. /**
  39. * DrawCommand实际命令的承载者 原来的历史得以在类中进行保存;
  40. * 如果构建新的命令xxxCommand的实现者,那么在原始记录中把新版的命令得以getXXx方法拿到,
  41. * 在进行的新的保存的,那么原始数据就可以在新的canvans中得以呈现。
  42. * (实际上canvas可以作为一个单例,在app中存在)
  43. */
  44. DrawCommand command = new DrawCommand(canvas, e.getPoint());
  45. ColorCommand colorCommand = new ColorCommand(canvas, Color.blue);
  46. history.append(colorCommand);
  47. history.append(command);
  48. colorCommand.execute();
  49. command.execute();
  50. }
  51. @Override
  52. public void mouseMoved(MouseEvent e) {
  53. }
  54. @Override
  55. public void windowOpened(WindowEvent e) {
  56. }
  57. @Override
  58. public void windowClosing(WindowEvent e) {
  59. System.exit(0);
  60. }
  61. @Override
  62. public void windowClosed(WindowEvent e) {
  63. }
  64. @Override
  65. public void windowIconified(WindowEvent e) {
  66. }
  67. @Override
  68. public void windowDeiconified(WindowEvent e) {
  69. }
  70. @Override
  71. public void windowActivated(WindowEvent e) {
  72. }
  73. @Override
  74. public void windowDeactivated(WindowEvent e) {
  75. }
  76. }

Command模式(命令设计模式)的更多相关文章

  1. 命令模式 Command 行为型 设计模式(十八)

    命令模式(Command) 请分析上图中这条命令的涉及到的角色以及执行过程,一种可能的理解方式是这样子的: 涉及角色为:大狗子和大狗子他妈 过程为:大狗子他妈角色 调用 大狗子的“回家吃饭”方法 引子 ...

  2. Java设计模式(22)命令模式(Command模式)

    Command模式是最让我疑惑的一个模式,我在阅读了很多代码后,才感觉隐约掌握其大概原理,我认为理解设计模式最主要是掌握起原理构造,这样才对自己实际编程有指导作用.Command模式实际上不是个很具体 ...

  3. python 设计模式之命令(Command)模式

    #写在前面 也了解了不少设计模式了,他们都有一个通病,那就是喜欢把简单的东西复杂化.比如在不同的类中加个第三者.哈哈哈,简单变复杂是有目的的,那就是降低耦合度,增强可维护性,提高代码复用性,使代码变得 ...

  4. 设计模式C++描述----19.命令(Command)模式

    一. 举例说明 我们知道,在多线程程序中,多个用户都给系统发 Read 和 Write 命令.这里有几点需要说明: 1. 首先明确一点,所有的这些 Read 和 Write 命令都是调用一个库函数. ...

  5. 设计模式之美:Command(命令)

    索引 别名 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):直接注入 Receiver 对象,Command 决定调用哪个方法. 实现方式(二):注入 Receiver 的指定方法, ...

  6. Command Pattern -- 命令模式原理及实现(C++)

    主要参考<大话设计模式>和<设计模式:可复用面向对象软件的基础>两本书.本文介绍命令模式的实现. What it is:Encapsulate a request as an ...

  7. 开发设计模式(一)Command模式

    Command定义 将来自客户端的请求传入一个对象,无需了解这个请求激活的 动作或有关接受这个请求的处理细节. 这是一种两台机器之间通讯联系性质的模式,类似传统过程语 言的 CallBack功能. 优 ...

  8. 设计模式之Command(命令)(转)

    Command模式是最让我疑惑的一个模式,我在阅读了很多代码后,才感觉隐约掌握其大概原理,我认为理解设计模式最主要是掌握起原理构造,这样才对自己实际编程有指导作用.Command模式实际上不是个很具体 ...

  9. Command Pattern 命令模式

    定义: 命令模式将‘请求’封装成对象,以便使用不同的请求,队列或者日志来参数化其他对象,命令模式也支持可撤销的操作. 类图 如上图所示:Command类是用来声明执行操作的接口:ConcreteCom ...

随机推荐

  1. Mybatis学习--Sql语句构建器

    学习笔记,选自Mybatis官方中文文档:http://www.mybatis.org/mybatis-3/zh/statement-builders.html 问题 Java程序员面对的最痛苦的事情 ...

  2. 使用IronPython集成Python和.NET

    本文由 伯乐在线 - 艾凌风 翻译,Daetalus 校稿.未经许可,禁止转载!英文出处:www.informit.com.欢迎加入翻译组. 从两个优秀的世界各取所需,更高效的复用代码.想想就醉了,. ...

  3. GrayCode for state machine

    How & Why use Gray Code A gray counter is a binary counter where only one bit changes at a time. ...

  4. java基础知识(5)---继承

    继 承:(面向对象特征之一)好处:1:提高了代码的复用性.2:让类与类之间产生了关系,提供了另一个特征多态的前提. 父类的由来:其实是由多个类不断向上抽取共性内容而来的.java中对于继承,java只 ...

  5. C语言学习笔记--const 和 volatile关键字

    1.const关键字 (1)const 修饰的变量是只读的,它不是真正的常量,本质还是变量,只是告诉编译器不能出现在赋值号左边! (2)const 修饰的局部变量在栈上分配空间 (3)const 修饰 ...

  6. SQL一对多特殊查询,取唯一一条

    主表: 辅表: 一个app对应多个apk,现在要取上线(Apk_Status最大的)的应用 select * from [dbo].[tbl_APP] as app join ( * from tbl ...

  7. MySQL绿色版的安装步骤

    由于工作需要最近要开始研究MySQL了(看来学习都是逼出来的),本人对mysql没有研究,可以说一个小白. 下面就从安装开始吧,虽然网上关于这方面的东西很多,还是需要自己把操作过程写下来. 1.数据库 ...

  8. [51nod1138]正整数分解为几个连续自然数之和

    解题关键:注意为什么上界是$\sqrt {2n} $ 因为函数是关于m的递减函数,而结果必须为正整数 $a = \frac{{2n + m - {m^2}}}{{2m}} = \frac{n}{m} ...

  9. SpringSecurity04 利用JPA和SpringSecurity实现前后端分离的认证和授权

    1 环境搭建 1.1 环境说明 JDK:1.8 MAVEN:3.5 SpringBoot:2.0.4 SpringSecurity:5.0.7 IDEA:2017.02旗舰版 1.2 环境搭建 创建一 ...

  10. layui 表格新增删除一行

    1.html 代码 <div class="layui-row layui-col-space5"> <div> <span style=" ...