Talk:Command pattern

From Wikipedia, the free encyclopedia
Jump to: navigation, search
WikiProject Computing (Rated Start-class)
WikiProject icon This article is within the scope of WikiProject Computing, a collaborative effort to improve the coverage of computers, computing, and information technology on Wikipedia. If you would like to participate, please visit the project page, where you can join the discussion and see a list of open tasks.
Start-Class article Start  This article has been rated as Start-Class on the project's quality scale.
 ???  This article has not yet received a rating on the project's importance scale.
 
WikiProject Computer science (Rated Start-class, Mid-importance)
WikiProject icon This article is within the scope of WikiProject Computer science, a collaborative effort to improve the coverage of Computer science related articles on Wikipedia. If you would like to participate, please visit the project page, where you can join the discussion and see a list of open tasks.
Start-Class article Start  This article has been rated as Start-Class on the project's quality scale.
 Mid  This article has been rated as Mid-importance on the project's importance scale.
 

Is the example helpful?[edit]

I'm a little worried that the example code here just isn't helpful. As written, the extra indirection of objects with an execute() method serves no purpose. It would be better to have an example that features some sort of queue (or scheduler or whatever you want to call it) so that the asynchronous aspect of the command execution is emphasised, i.e. the command gets run possibly some time after it is invoked, and the invoker might be in a different thread to the receiver. —Preceding unsigned comment added by 81.105.217.34 (talk) 15:42, 20 April 2010 (UTC)

Sub-pattern of Command and ConcreteCommand?[edit]

What is called the sub-pattern consisting of only Command interface and class ConcreteCommand? This is an important pattern in itself, without the transactional additions, which can effectively replace function objects and allow lambda calculus to be translated to Java code.

88.112.121.61 (talk) 23:29, 9 March 2010 (UTC)

Python examples[edit]

I'm not sure if Python is the best language to use for Design Pattern examples. Perhaps the main examples should be in a common language like Visual Basic or Java and there should be separate pages for examples in less popular languages. I'm not a Java programmer so I can't make this change. I would be happy to provide Delphi or C# examples.

I agree. In the real world, Python would use closures for those examples. Particularly, statements like "Generic code that operates on command objects can be powerful and flexible while providing a simple API.", in the context of Python, sound absurd: how are they simpler or more powerful than plain callable objects?
(Arguably, the "Command Pattern" would begin to make sense in Python once you start using it to handle undo functionality and such, as described on the C2 wiki page. However, none of the examples in the article do that kind of thing.)
Tangentially, this article could probably be much improved by a comparison with closures --Piet Delport 10:06, 1 June 2006 (UTC)
In an FP language, you would use closures and curried functions for everything mentioned here, including the undo stack. What's left, however, still follows the command pattern, even though it is no longer object-oriented. A curried function is a function whose argument list is generated at runtime (usually with a function named "apply"). A Common Lisp version of the C++ example demonstrates this:
(defun ingredient (amount what)
  (format t " * Add ~a of ~a~%" amount what)) ;; FORMAT is Lisp's printf.
 
(defun step (action time)
  (format t " * ~a for ~a~%" action time))
 
(defvar *recipe* `((,#'ingredient "2 tablespoons" "vegetable oil")
		   (,#'ingredient "3 cups" "rice")
		   (,#'step "Stir-fry" "3-4 minutes")
		   (,#'ingredient "4 ounces" "peas")
		   (,#'ingredient "1 teaspoon" "soy sauce")))
 
(loop for command in *recipe* do
      (apply (car command) (cdr command)))

It does basically everything that the C++ version does. Since sending data to STDOUT is not an undoable operation in principle, no undo function was provided. However, it is conceivable to associate each function and its arguments with an undo counterpart, using a hash table:

(defvar *undo* (make-hash-table :test 'equalp))
 
;; The setf calls define HOW to undo an operation. Each undo
;; operation is keyed to the function it undoes, and takes
;; the same arguments as the original function.
 
(setf (gethash #'ingredient *undo*)
      (lambda (&rest args) (format t "FORGET I SAID THAT!!!~%")))
(setf (gethash #'step *undo*)
      (lambda (&rest args) (format t "FORGET I SAID THAT!!!~%")))
 
;; The undo function invokes the undo-function defined for
;; a command, with the argument list of the command.
 
(defun undo (command) 
  (apply (gethash (car command) *undo*)
	 (cdr command)))

98.31.54.35 (talk) 23:47, 5 July 2008 (UTC)

You know... removing this example was a mistake. The C++ example is unhelpful. The Python example was working code.
If Python is less popular than Java, a good fix would be to rewrite the example in Java. (Duh.)
As for the idea that Python programmers would use closures for this... well, it strikes me as kinda weird. I doubt many would. Python isn't Scheme. In Python, using an object is more flexible. You can add a priority and change the threadpool to understand priority. You can modify the object after it's created. You can examine the fields. You can find ways to merge similar objects. You can serialize it. You can populate it one field at a time (as in a wizard). And so on.
So while your objections may be sound, deleting the example was not the right action. I'm putting it back and I challenge you to improve upon it. --Jorend 13:50, 2 April 2007 (UTC)
Here is an example written in java, but I'm not 100% sure it is good enough. I'm posting it here. Requires jre 1.5 or later, working example ( but meaningless )
with Callable<E>

package org.designPatterns.command;

import java.util.concurrent.Callable;

/**

  • Contains 2 numbers and returns their sum on call()
  • /

public class SumCommand implements Callable<Integer> {

private int param1; // both have default value of 0
private int param2;
public SumCommand() {
/* do nothing in this case */
}
/**
  • Fully initializes the inner state of the object
  • @param param1
  • @param param1
  • /
public SumCommand(int param1, int param2){
this.param1 = param1;
this.param2 = param2;
}
/**
  • @return param1+param2
  • /
public Integer call() throws Exception {
/* big delay due to some operations */
Thread.sleep(1000);
return param1+param2;
}
/* getters and setters omited ...*/
/* ... */

}

with Runnable

package org.designPatterns.command;

/**

  • holds an integer and increments it with a given value every time the run method is called
  • /

public class IncrementCommand implements Runnable {

private int value;
private int incrementer;
public IncrementCommand(int value, int incrementer){
this.value = value;
this.incrementer = incrementer;
}
/**
  • The operation of this Command affects an object contained in it, it DOES NOT return a value
  • /
public void run() {
/* big delay due to some operations */
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (this) {
this.value+=incrementer;
}
}
public int getValue() {
return value;
}

}

Main method for demonstrating both of them:

package org.designPatterns.command;

import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit;

/**

  • This class demonstrates usage of the command classes with and without thread pool
  • /

public class Main {

public static void main(String[] args) throws Exception {
/* simple example with callable, expected 9:*/
System.out.println( "new SumCommand(4,5).call() : " + new SumCommand(4,5).call() );
/* and setting up the command object */
IncrementCommand ac = new IncrementCommand( 5,1 );
ac.run();
System.out.println( "new IncrementCommand( 5,1 ); after run() :"+ac.getValue() );
/*with Thread pool:*/
IncrementCommand aggregator = new IncrementCommand(3,2);
SumCommand summator = new SumCommand(3,6);
Future<Integer> res1;
Future<IncrementCommand> res2;
ExecutorService executor = new ThreadPoolExecutor(2,6,100l,TimeUnit.SECONDS,new LinkedBlockingQueue<Runnable>() );
/*one call*/
res1 = executor.submit(summator); /*Callable*/
res2 = executor.submit(aggregator, aggregator); /*Runnable*/
/* DO SOMETHING ELSE TIMETAKING HERE */
System.out.println("expects (3+6) = 9: "+res1.get());
System.out.println("expects ( 3+ 2) = 5 :"+res2.get().getValue());
executor.shutdown();
executor.awaitTermination(10, TimeUnit.SECONDS);
}

} P.S. No idea how to make it appear correctly formated :( Oubless 09:48, 19 September 2007 (UTC)

Link to P of EAA : UnitOfWorks[edit]

The link to martin's fowler website, which redirect to a description of the UnitOfWork pattern does not seems appropriate. Are you sure that UnitOfWork is connected to the command pattern ? If so, some text should explain the link... —The preceding unsigned comment was added by 195.68.44.148 (talk) 14:31, 26 April 2007 (UTC).

Programming Code[edit]

Since the subject is a topic in computer science, the general explanations should not use a specific programming languages (Java, Python, or whatever) but should be written in pseudocode. Actual code examples (in many languages, preferably) can be shown at the end of the article. Inquam 07:56, 7 November 2007 (UTC)

C++ example[edit]

I added a simple c++ example. Let me know what you think.--Michael miceli (talk) 22:32, 7 April 2008 (UTC)

I realise this is entirely the subject of the argument above, but I'm not sure C++ is optimal for this; there's a lot of stuff that can be difficult to understand in it. Seems as though Python, which would perhaps lead to a terser example, isn't well-loved either. Would re-writing in Java (it's OO and as ubiquitous as they come) make sense? Scala would make this look great but it's not used by anyone :( --zootm (talk) 11:31, 5 June 2008 (UTC)
Look at how byzantine the Java example above is, then ask that question again. COBOL was once ubiquitous, too. 98.31.54.35 (talk) 01:40, 6 July 2008 (UTC)
Super late reply: Given that the comparable C++ example would be only more complex it seems a bad thing to contrast with, though. Java was the suggestion since it seems to be widely used on here, something simpler might be better, but C++ ain't that. --zootm (talk) 12:53, 2 September 2009 (UTC)
I don't see why it is bad to include a C++ example... it might not be simple or explain the pattern easily, but wouldn't it be helpful for people who are wishing to implement this pattern in C++? Crhopkins (talk) 15:49, 5 January 2010 (UTC)
It's a slippery slope. Look at the histories of any of the Design Pattern pages to see these patterns in every language imaginable. See Talk:Design_pattern_(computer_science)#Extraneous_Examples for my thread that lead to massive cleanup. I'm all for having endless examples in everyone's favorite languages somewhere, like Wikibooks, and having these pages link to them, but these Wikipedia pages should get across the idea of the pattern, not be an implementation cookbook. If it helps the explanation to have multiple languages, then by all means, but in general one language is more than enough. Much as I've never actually used Java, I like it for these example because it is widely-used, strongly-typed, and has garbage collection. With a language without strong typing, many design patterns are harder to follow (because no abstract iterface is needed); the raison d'être of some design patterns even depends on abstract interfaces, so while I love Python for algorithm examples (where working Python is almost as easy to follow as pseudocode), Python is often not a good example language for classic OO design patterns. Similarly, a language without garbage collection (like C++) adds complexity to examples that isn't necessary. While COBOL was once ubiquitous, and while Java will probably never be the dominant language, Java is the most-used language with the features for which the Gang-of-Four Design Patterns were created, not to mention both came out in the same year (1995, fifteen years ago(!); the age of the Pentium Pro). (Similarly, RAII is best exemplified in C++, with its deterministic scope-based destruction.) —Ben FrantzDale (talk) 14:45, 6 January 2010 (UTC)

Image wrong?[edit]

Command Design Pattern Class Diagram.png

In Command Design Pattern Class Diagram.png's current version, there is a UML comment on the Receiver class that reads: At some time asks to execute the command. Invoker has exactly the same comment. Why should a Receiver execute commands on it self? Thanks, --134.91.225.10 (talk) 12:40, 17 October 2008 (UTC) (User:Abdull)

Problem still exists. The text at the Receiver should be something like "Is sometimes asked to be executed" or "Will be executed some time". —Preceding unsigned comment added by 141.52.232.84 (talk) 16:23, 23 February 2010 (UTC)
Is fixed now. --Abdull (talk) 16:40, 11 March 2013 (UTC)

Criticism of Switch is ambiguous[edit]

I'm not sure I understand the point of the criticism of the switch. The switch is the implementation of the command's invoker. When the article claims the switch itself should not be aware of any lamp details, is it claiming that the invoker shouldn't be aware of any lamp details? Or is it saying that the switch isn't a good example of an invoker, because a good switch class has an additional restriction that an invoker doesn't need? If I'm reading this article, I don't need to know if the switch class is a good way to model a circuit, I need to know what constitutes a good invoker when the command pattern is used. —MiguelM (talk) 22:39, 21 June 2010 (UTC)

Bad article ![edit]

The example is from javaworld (http://www.javaworld.com/javatips/jw-javatip68.html). Someone said about that:"Nice article, but violates basic principles of reknown OO expert". You can read in GoF: "It's easy to add new Commands, because you don't have to change existing classes". In your example you don't have to define the interface Command. Suppose you want to command a 3-state receiver. You have to change the code in PressSwitch and Switch classes. Maybe is better to copy from GoF !. 86.107.49.197 (talk) 18:14, 29 December 2010 (UTC)

javascript example[edit]

storeAndExecute only execute in javascript, it doesn't store...

/* The Invoker function */
var Switch = function(){
    this.storeAndExecute = function(command){
        command.execute();
    }
}

78.153.242.236 (talk) 14:36, 22 February 2013 (UTC)