// Purpose. Command design pattern - decoupling producer from consumer import java.util.*; public class CommandQueue { interface Command { void execute(); } static class DomesticEngineer implements Command { public void execute() { System.out.println( "take out the trash" ); } } static class Politician implements Command { public void execute() { System.out.println( "take money from the rich, take votes from the poor" ); } } static class Programmer implements Command { public void execute() { System.out.println( "sell the bugs, charge extra for the fixes" ); } } public static List produceRequests() { List queue = new ArrayList(); queue.add( new DomesticEngineer() ); queue.add( new Politician() ); queue.add( new Programmer() ); return queue; } public static void workOffRequests( List queue ) { for (Iterator it = queue.iterator(); it.hasNext(); ) ((Command)it.next()).execute(); } public static void main( String[] args ) { List queue = produceRequests(); workOffRequests( queue ); }} // take out the trash // take money from the rich, take votes from the poor // sell the bugs, charge extra for the fixes // Purpose. Java reflection and the Command design pattern // // Motivation. "Sometimes it is necessary to issue requests to objects without // knowing anything about the operation being requested or the receiver of the // request." The Command design pattern suggests encapsulating ("wrapping") in // an object all (or some) of the following: an object, a method name, and some // arguments. Java does not support "pointers to methods", but its reflection // capability will do nicely. The "command" is a black box to the "client". // All the client does is call "execute()" on the opaque object. import java.lang.reflect.*; public class CommandReflect { private int state; public CommandReflect( int in ) { state = in; } public int addOne( Integer one ) { return state + one.intValue(); } public int addTwo( Integer one, Integer two ) { return state + one.intValue() + two.intValue(); } static public class Command { private Object receiver; // the "encapsulated" object private Method action; // the "pre-registered" request private Object[] args; // the "pre-registered" arg list public Command( Object obj, String methodName, Object[] arguments ) { receiver = obj; args = arguments; Class cls = obj.getClass(); // get the object's "Class" Class[] argTypes = new Class[args.length]; for (int i=0; i < args.length; i++) // get the "Class" for each argTypes[i] = args[i].getClass(); // supplied argument // get the "Method" data structure with the correct name and signature try { action = cls.getMethod( methodName, argTypes ); } catch( NoSuchMethodException e ) { System.out.println( e ); } } public Object execute() { // in C++, you do something like --- return receiver->action( args ); try { return action.invoke( receiver, args ); } catch( IllegalAccessException e ) { System.out.println( e ); } catch( InvocationTargetException e ) { System.out.println( e ); } return null; } } public static void main( String[] args ) { CommandReflect[] objs = { new CommandReflect(1), new CommandReflect(2) }; System.out.print( "Normal call results: " ); System.out.print( objs[0].addOne( new Integer(3) ) + " " ); System.out.print( objs[1].addTwo( new Integer(4), new Integer(5) ) + " " ); Command[] cmds = { new Command( objs[0], "addOne", new Integer[] { new Integer(3) } ), new Command( objs[1], "addTwo", new Integer[] { new Integer(4), new Integer(5) } ) }; System.out.print( "\nReflection results: " ); for (int i=0; i < cmds.length; i++) System.out.print( cmds[i].execute() + " " ); System.out.println(); } } // Normal call results: 4 11 // 1 + 3 = 4 // 2 + 4 + 5 = 11 // Reflection results: 4 11