Date: Mon, 08 Feb 1999 09:03:35 -0500 From: Paul TremblettAdd to Address Book Reply-To: Paul_Tremblett@beechwood.com Organization: Beechwood Data Systems To: bparanj@yahoo.com Subject: Your Article Bala, For some reason or another, every attempt to open the email containing the link to you article in JavaWorld is blowing away my browser and generating a feedback dialog which I sent off to Netscape. So, I went to javaWorld and read the article that way and I can honestly say it ranks among the best article I have read. If there's one thing I've always enjoyed in all the years I have been in this business, it's seeing someone finding a more elegant solution and I've always felt a certain pity for those programmers who felt threatened by something better than what they had done - they're the unfortunate ones since they deprive themselves taking advantage of the world's best way of learning. I learned something from you article and for that I salute you and thank you. I have two small questions: 1. Have you ever thought of submitting an article to Dr. Dobbs? They are a great group to work with. It won't make you rich but it's quite rewarding. If you check out the March issue, you'll see something else from me. 2. Would my guess that you have a background in Smalltalk be an accurate one? If you do, it explains your insight. If you don't, I can guarantee you'd be a member in good standing of the Smalltalk community. Congratulations and best wishes, Paul Tremblett From: JMartin@xypoint.comAdd to Address Book To: bala.paranj@javaworld.com Subject: Comments on Java Tip 68 Date: Wed, 10 Feb 1999 14:47:25 -0800 I found two problems. Of course these are just my opinions. :-) 1. The callback semantics of the command pattern were over emphasized. Although the Command pattern can replace C-like function pointer callbacks, the intent of the pattern is much broader than callbacks. Other patterns like Observer and Strategy would also be examples of ways to handle callbacks. Including discussion of the callback problem detracts from the motivation and intent of the Command pattern. This discussion should probably be moved into a sidebar separate from the rest of the article. 2. The Switch/Fan/Light example is not a good demonstration of the capabilities of the Command pattern. From the motivation section in GOF: "This [Command] object can be stored and passed around like other objects." The problem is that the Switch sample does nothing with the Command objects after they are created. In your Switch example you state, "We see that the Fan and the Light have different interfaces, which means the Switch has to be independent of the Receiver interface..." I think that this problem would be better solved by the Adapter pattern, whose intent according to GOF is to "Convert the interface of a class into another interface that clients expect." Applying the Adapter pattern: - The Fan and Light are Adaptee classes. - The Light*Command and Fan*Command classes would be Adapter classes implementing a specific Target interface used by the Switch ================== Other than those two points, I thought the tip was good. I particularly liked the Transaction example: it was concise and meaningful. -Jeff Date: Thu, 11 Feb 1999 03:51:54 -0800 (PST) From: cjmurphy@ozemail.com.au (Chris Murphy)Add to Address Book To: bala.paranj@javaworld.com Subject: JavaWorld: Command Pattern article comment Good to see another Design Pattern article. Perhaps could have mentioned javax.swing.Action and related classes which have already been written for the Swing environment. I have one little question. Can you tell me what tool you used to draw the diagrams? ------------------------------------------------------------ From: "Neumeier, Brett M APX" Add to Address Book To: "'bala'" Subject: JavaWorld tip 68 Date: Fri, 19 Feb 1999 11:43:34 -0600 Dear Mr. Paranj, I was very interested in your tip regarding the Command pattern in Java. I'm curious, though, that you didn't use inner classes to implement the various Command objects. Below I've included my version of TestCommand, which (IMO) is a bit cleaner -- it takes advantage of the fact that inner classes "know about" their enclosing class, and greatly reduces the number of top-level classes in the system. There is room for further refactoring here; I'm inclined to make Fan and Light subclasses of an abstract Commandable type. But that really goes beyond the point I'm trying to make here. Thanks for listening, -Brett Neumeier class Fan { public void startRotate() { System.out.println("Fan is rotating"); } public void stopRotate() { System.out.println("Fan is not rotating"); } public Command onCommand() { return new Command() { public void execute() { startRotate(); } }; } public Command offCommand() { return new Command() { public void execute() { stopRotate(); } }; } } class Light { public void turnOn() { System.out.println("Light is lit"); } public void turnOff() { System.out.println("Light is extinguished"); } public Command onCommand() { return new Command() { public void execute() { turnOn(); } }; } public Command offCommand() { return new Command() { public void execute() { turnOff(); } }; } } class Switch { private Command upCommand, downCommand; public Switch (Command up, Command down) { upCommand = up; downCommand = down; } void flipUp() { upCommand.execute(); } void flipDown() { downCommand.execute(); } } public class TestCommand2 { public static void main(String[] args) { Light testLight = new Light(); Switch testSwitch = new Switch(testLight.onCommand(), testLight.offCommand()); testSwitch.flipUp(); testSwitch.flipDown(); Fan testFan = new Fan(); Switch testSwitch2 = new Switch(testFan.onCommand(), testFan.offCommand()); testSwitch2.flipUp(); testSwitch2.flipDown(); } } From: "Neumeier, Brett M APX" Add to Address Book To: "'Bala paranj'" Subject: RE: JavaWorld tip 68 Date: Tue, 23 Feb 1999 09:37:49 -0600 You are more than welcome; and thank you for the kind words. Incidentally, I went on and factored out the common behavior of Fan and Light as I suggested might be a good idea in my earlier email. I also added a convenience factory method in the new abstract Switchable class, to encapsulate Switch creation. In case you are at all interested, here's my final version of the code. I can't think of anything that could further improve it; can you? The driving motivation here is to make certain that each given piece of code appears once and only once in the program: a metric for program "goodness" that some of the programmers I admire most swear by. If you're not familiar with program refactoring (I wasn't, until fairly recently), I commend you to the web page: http://www2.awl.com/cseng/titles/0-201-89542-0/refactor/index.html which contains Martin Fowler's collection of common refactoring techniques. -bn class Switch { private Command upCommand, downCommand; public Switch (Command up, Command down) { upCommand = up; downCommand = down; } void flipUp() { upCommand.execute(); } void flipDown() { downCommand.execute(); } } abstract class Switchable { abstract void switchOn(); abstract void switchOff(); public Command onCommand() { return new Command() { public void execute() { switchOn(); } }; } public Command offCommand() { return new Command() { public void execute() { switchOff(); } }; } public Switch getSwitch() { return new Switch(onCommand(), offCommand()); } } class Fan extends Switchable { void switchOn() { System.out.println("Fan is rotating"); } void switchOff() { System.out.println("Fan is not rotating"); } } class Light extends Switchable { void switchOn() { System.out.println("Light is lit"); } void switchOff() { System.out.println("Light is extinguished"); } } public class TestCommand4 { public static void main(String[] args) { Light testLight = new Light(); Switch testSwitch = testLight.getSwitch(); testSwitch.flipUp(); testSwitch.flipDown(); Fan testFan = new Fan(); Switch testSwitch2 = testFan.getSwitch(); testSwitch2.flipUp(); testSwitch2.flipDown(); } } Date: Tue, 23 Mar 1999 12:42:01 +0900 From: Mohana Murali Gurunathan Add to Address Book Organization: Enterprise Solutions, Wipro InfoTech To: Bala paranj Subject: Re: JavaWorld: an improvement!? Hello , I had the opportunity to spend some time with the article again ( reading it for a second or third time gives more understanding or makes the concepts clear). My feedback : Suppose that we have a reusable library having classes like Fan, Light, Normally we should not modify them. One option is either subclass or the other option is to use this Command Pattern. I think that the Command Pattern is far superior when considering our feedbacks ( My feedback + Mr. Brett Neumeier), as we are modifying the Server classes ( Fan and Light). Moreover the second feedback given by Mr.Brett Neumeier is not ok (thought he has done factoring) as the Fan and Light classes have the same methods to access them. I also read the "Transaction" and your presentation was nice. with thanks and best regards, Murali Date: Tue, 16 Mar 1999 13:38:59 -0800 (PST) From: prasad@gtx.com (Trivikram Prasad)Add to Address Book To: bala.paranj@javaworld.com Subject: JavaWorld: RE:Learn how to implement the Command Pattern Your article on implementing the Command Pattern was extremely useful. It was very well written and easy to understand and the examples were great. Thanks Trivikram Prasad ------------------------------------------------------------