Design Pattern - Command(Java)

àì夳堔傛蜴生んèń 2022-05-20 04:35 103阅读 0赞

分享一个大牛的人工智能教程。零基础!通俗易懂!风趣幽默!希望你也加入到人工智能的队伍中来!请点击http://www.captainbed.net

Definition

Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations.

Participants

  1. The classes and/or objects participating in this pattern are:
  • Command (Command)

    • Declares an interface for executing an operation
  • ConcreteCommand (CalculatorCommand)

    • Defines a binding between a Receiver object and an action
    • Implements Execute by invoking the corresponding operation(s) on Receiver
  • Client (CommandApp)

    • Creates a ConcreteCommand object and sets its receiver
  • Invoker (User)

    • Asks the command to carry out the request
  • Receiver (Calculator)

    • Knows how to perform the operations associated with carrying out the request.

Sample Code in Java


This structural code demonstrates the Command pattern which stores requests as objects allowing clients to execute or playback the requests.

  1. package chimomo.learning.java.designpattern.command.sample;
  2. /**
  3. * The 'Command' abstract class
  4. *
  5. * @author Chimomo
  6. */
  7. abstract class Command {
  8. // The receiver
  9. final Receiver receiver;
  10. /**
  11. * Initializes a new instance of the "Command" class
  12. *
  13. * @param receiver The receiver
  14. */
  15. Command(Receiver receiver) {
  16. this.receiver = receiver;
  17. }
  18. /**
  19. * Execute
  20. */
  21. public abstract void execute();
  22. }
  23. package chimomo.learning.java.designpattern.command.sample;
  24. /**
  25. * The 'ConcreteCommand' class
  26. *
  27. * @author Chimomo
  28. */
  29. class ConcreteCommand extends Command {
  30. /**
  31. * Initializes a new instance of the "ConcreteCommand" class
  32. *
  33. * @param receiver The receiver
  34. */
  35. ConcreteCommand(Receiver receiver) {
  36. super(receiver);
  37. }
  38. /**
  39. * Execute
  40. */
  41. @Override
  42. public void execute() {
  43. this.receiver.action();
  44. }
  45. }
  46. package chimomo.learning.java.designpattern.command.sample;
  47. /**
  48. * The 'Invoker' class
  49. *
  50. * @author Chimomo
  51. */
  52. class Invoker {
  53. // The command
  54. private Command command;
  55. /**
  56. * Execute command
  57. */
  58. void executeCommand() {
  59. this.command.execute();
  60. }
  61. /**
  62. * Set command
  63. *
  64. * @param command The command
  65. */
  66. public void setCommand(Command command) {
  67. this.command = command;
  68. }
  69. }
  70. package chimomo.learning.java.designpattern.command.sample;
  71. /**
  72. * Startup class for Structural Command Design Pattern
  73. *
  74. * @author Chimomo
  75. */
  76. class Program {
  77. /**
  78. * Entry point into console application
  79. *
  80. * @param args The arguments
  81. */
  82. public static void main(String[] args) {
  83. // Create receiver, command, and invoker.
  84. Receiver receiver = new Receiver();
  85. Command command = new ConcreteCommand(receiver);
  86. Invoker invoker = new Invoker();
  87. // Set and execute command
  88. invoker.setCommand(command);
  89. invoker.executeCommand();
  90. }
  91. }
  92. /* ------ Running Results ------
  93. Called Receiver.action()
  94. */
  95. package chimomo.learning.java.designpattern.command.sample;
  96. /**
  97. * The 'Receiver' class
  98. *
  99. * @author Chimomo
  100. */
  101. class Receiver {
  102. /**
  103. * The action
  104. */
  105. void action() {
  106. System.out.println("Called Receiver.action()");
  107. }
  108. }

This real-world code demonstrates the Command pattern used in a simple calculator with unlimited number of undo’s and redo’s.

  1. package chimomo.learning.java.designpattern.command.realworld;
  2. /**
  3. * The 'Receiver' class
  4. *
  5. * @author Chimomo
  6. */
  7. class Calculator {
  8. // The current value
  9. private int currentValue;
  10. /**
  11. * The operation
  12. *
  13. * @param operand The operand
  14. */
  15. public void operation(char operator, int operand) {
  16. switch (operator) {
  17. case '+':
  18. this.currentValue += operand;
  19. break;
  20. case '-':
  21. this.currentValue -= operand;
  22. break;
  23. case '*':
  24. this.currentValue *= operand;
  25. break;
  26. case '/':
  27. this.currentValue /= operand;
  28. break;
  29. }
  30. System.out.println(String.format("Current value = %3d (following %s %d)", this.currentValue, operator, operand));
  31. }
  32. }
  33. package chimomo.learning.java.designpattern.command.realworld;
  34. /**
  35. * The 'ConcreteCommand' class
  36. *
  37. * @author Chimomo
  38. */
  39. class CalculatorCommand extends Command {
  40. // The calculator
  41. private final Calculator calculator;
  42. // The operator
  43. private char operator;
  44. // The operand
  45. private int operand;
  46. /**
  47. * Initializes a new instance of the "CalculatorCommand" class
  48. *
  49. * @param calculator The calculator
  50. * @param operator The operator
  51. * @param operand The operand
  52. */
  53. CalculatorCommand(Calculator calculator, char operator, int operand) {
  54. this.calculator = calculator;
  55. this.operator = operator;
  56. this.operand = operand;
  57. }
  58. /**
  59. * Execute
  60. */
  61. @Override
  62. public void execute() {
  63. this.calculator.operation(this.operator, this.operand);
  64. }
  65. /**
  66. * Unexecute
  67. */
  68. @Override
  69. public void unExecute() {
  70. this.calculator.operation(this.undo(this.operator), this.operand);
  71. }
  72. /**
  73. * undo
  74. *
  75. * @return The undo operator
  76. */
  77. private char undo(char operator) {
  78. switch (operator) {
  79. case '+':
  80. return '-';
  81. case '-':
  82. return '+';
  83. case '*':
  84. return '/';
  85. case '/':
  86. return '*';
  87. default:
  88. throw new IllegalArgumentException("operator: " + operator);
  89. }
  90. }
  91. }
  92. package chimomo.learning.java.designpattern.command.realworld;
  93. /**
  94. * The 'Command' abstract class
  95. *
  96. * @author Chimomo
  97. */
  98. abstract class Command {
  99. /**
  100. * Execute
  101. */
  102. public abstract void execute();
  103. /**
  104. * Unexecute
  105. */
  106. public abstract void unExecute();
  107. }
  108. package chimomo.learning.java.designpattern.command.realworld;
  109. /**
  110. * Startup class for Real-World Command Design Pattern
  111. *
  112. * @author Chimomo
  113. */
  114. class Program {
  115. /**
  116. * Entry point into console application
  117. *
  118. * @param args The arguments
  119. */
  120. public static void main(String[] args) {
  121. // Create user and let her compute
  122. User user = new User();
  123. // User presses calculator buttons
  124. user.compute('+', 100);
  125. user.compute('-', 50);
  126. user.compute('*', 10);
  127. user.compute('/', 2);
  128. // undo 4 commands
  129. user.undo(4);
  130. // redo 3 commands
  131. user.redo(3);
  132. }
  133. }
  134. /* ------ Running Results ------
  135. Current value = 100 (following + 100)
  136. Current value = 50 (following - 50)
  137. Current value = 500 (following * 10)
  138. Current value = 250 (following / 2)
  139. ---- undo 4 levels
  140. Current value = 500 (following * 2)
  141. Current value = 50 (following / 10)
  142. Current value = 100 (following + 50)
  143. Current value = 0 (following - 100)
  144. ---- redo 3 levels
  145. Current value = 100 (following + 100)
  146. Current value = 50 (following - 50)
  147. Current value = 500 (following * 10)
  148. */
  149. package chimomo.learning.java.designpattern.command.realworld;
  150. import java.util.ArrayList;
  151. import java.util.List;
  152. /**
  153. * The 'Invoker' class
  154. *
  155. * @author Chimomo
  156. */
  157. class User {
  158. // The calculator
  159. private final Calculator calculator = new Calculator();
  160. // The commands
  161. private final List<Command> commands = new ArrayList<>();
  162. // The current command
  163. private int currentCommand;
  164. void compute(char operator, int operand) {
  165. // Create command operation and execute it
  166. Command command = new CalculatorCommand(this.calculator, operator, operand);
  167. command.execute();
  168. // Add command to undo list
  169. this.commands.add(command);
  170. this.currentCommand++;
  171. }
  172. /**
  173. * Redo
  174. *
  175. * @param levels The levels to redo
  176. */
  177. void redo(int levels) {
  178. System.out.println(String.format("---- redo %d levels ", levels));
  179. // Perform redo operations
  180. for (int i = 0; i < levels; i++) {
  181. if (this.currentCommand < this.commands.size() - 1) {
  182. Command command = this.commands.get(this.currentCommand++);
  183. command.execute();
  184. }
  185. }
  186. }
  187. /**
  188. * Undo
  189. *
  190. * @param levels The levels to undo
  191. */
  192. void undo(int levels) {
  193. System.out.println(String.format("---- undo %d levels ", levels));
  194. // Perform undo operations
  195. for (int i = 0; i < levels; i++) {
  196. if (this.currentCommand > 0) {
  197. Command command = this.commands.get(--this.currentCommand);
  198. command.unExecute();
  199. }
  200. }
  201. }
  202. }

发表评论

表情:
评论列表 (有 0 条评论,103人围观)

还没有评论,来说两句吧...

相关阅读