1. 封装命令
  2. 结合cor实现undo
    1. ctrl+z回退操作
    2. 是用Command模式来实现的
  3. 用得挺多的,可能用的没感觉到

解析

  • 别名:Action/Transaction
  • Command封装了一个命令,比如菜单上的命令
  • 命令要执行,必须要有个doit();或者exec();或者run();或者方法(不叫do是因为java中有do关键字)
  • 要实现undo功能要有个undo();方法
  • 要实现undo功能,do和undo要配着对来
  • 如何实现一连串的undo?
    • 责任链(无限拓展)===>FilterChain类+Filter接口及其实现类
    • Command可以无限拓展,通过继承来扩展,但是容易造成类臃肿(违背单一职责原则……)
    • 所有的Command都要放到一个列表List中去
  • 动作:菜单的动作
  • 事务:不能有中间状态(要么完成要么不完成)
  • 宏命令:word===>命令是由好多个一连串的命令组成的大命令
    • command与组合composite模式===>树状结构
    • 继承、聚合、组成是类与类间的关系,不是设计模式
  • 多次undo
    • command与责任链cor模式
  • transaction回滚
    • command与记忆模式(备忘录模式?)

URL类图

image.png

例子:命令回退

Content类

  1. package com.mashibing.dp.command;
  2. public class Content {
  3. String msg = "hello everybody ";
  4. }

Command类

  1. package com.mashibing.dp.command;
  2. public abstract class Command {
  3. public abstract void doit(); //exec run
  4. public abstract void undo();
  5. }

CopyCommand类

  1. package com.mashibing.dp.command;
  2. public class CopyCommand extends Command {
  3. Content c;
  4. public CopyCommand(Content c) {
  5. this.c = c;
  6. }
  7. @Override
  8. public void doit() {
  9. c.msg = c.msg + c.msg;
  10. }
  11. @Override
  12. public void undo() {
  13. c.msg = c.msg.substring(0, c.msg.length()/2);
  14. }
  15. }

DeleteCommand类

  1. package com.mashibing.dp.command;
  2. public class DeleteCommand extends Command {
  3. Content c;
  4. String deleted;
  5. public DeleteCommand(Content c) {
  6. this.c = c;
  7. }
  8. // 删除前5个字符
  9. @Override
  10. public void doit() {
  11. deleted = c.msg.substring(0, 5);
  12. c.msg = c.msg.substring(5, c.msg.length());
  13. }
  14. @Override
  15. public void undo() {
  16. c.msg = deleted + c.msg;
  17. }
  18. }

InsertCommand类

  1. package com.mashibing.dp.command;
  2. public class InsertCommand extends Command {
  3. Content c;
  4. String strToInsert = "http://www.mashibing.com";
  5. public InsertCommand(Content c) {
  6. this.c = c;
  7. }
  8. @Override
  9. public void doit() {
  10. c.msg = c.msg + strToInsert;
  11. }
  12. @Override
  13. public void undo() {
  14. c.msg = c.msg.substring(0, c.msg.length()-strToInsert.length());
  15. }
  16. }

命令回退的使用

  1. package com.mashibing.dp.command;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. public class Main {
  5. public static void main(String[] args) {
  6. Content c = new Content();
  7. Command insertCommand = new InsertCommand(c);
  8. // 默认插入http://www.mashibing.com
  9. insertCommand.doit();
  10. insertCommand.undo();
  11. Command copyCommand = new CopyCommand(c);
  12. insertCommand.doit();
  13. insertCommand.undo();
  14. Command deleteCommand = new DeleteCommand(c);
  15. deleteCommand.doit();
  16. deleteCommand.undo();
  17. List<Command> commands = new ArrayList<>();
  18. commands.add(new InsertCommand(c));
  19. commands.add(new CopyCommand(c));
  20. commands.add(new DeleteCommand(c));
  21. for(Command comm : commands) {
  22. comm.doit();
  23. }
  24. System.out.println(c.msg);
  25. for(int i= commands.size()-1; i>=0; i--) {
  26. commands.get(i).undo();
  27. }
  28. System.out.println(c.msg);
  29. }
  30. }