Reflections bad or good practice for commands - java

Well, I saw there were some questions and answers about this, but they didn't really satisfy me.
Let's say for example, I have programmed a console. It's a nice JFrame with an output and an input txtField/Area. But this console should not only be used for output, but also to run commands.
Because I would need this console very often and I don't want to change the code of the console I programmed it this way:
The console has one method to register commands.
console.registerCommand(String command, String methodToInvoke, Object invokeObject);
With this method I'm able to use this console everywhere without the need of changing or inharitance.
Whenever the String command is written the console knows it's a registered keyword and executes the method via reflection.
Would this be a good or bad practice? On code styling and in performance! And what could I do better?
I also found it quite neat to use reflections this way to add ActionListeners to MenuItems in a TrayIcon.
Edit
To the Answer below:
Ok with commands i would accept this is a way to do. But in the Tray example I wrote a TrayHelper Class which creates the TrayIcon. There I want to add MenuItems and their ActionListeners but without creating every Object myself and add them to the Tray. So I wrote Methods like this:
public void addMenuItem(String label, String methodToInvoke, String invokeObject);
This method not only executes the method when the MenuItem is clicked, but also creates the MenuItem first, adds an ActionListener to it which invokes the Method, and adds it to the TrayIcon.
So in order to use this TrayHelper I can now just write:
th.addMenuItem("Exit","exitMethod",this);//executes the exitMethod of
//this class after Menuitem Exit
//was clicked
I don't really see how i could do this without reflection other than to write all the Objects myself again and adding them to the Tray. Or I'm blind :)
Edit 2
Ok, I was blind. I just didn't realize how to do this without reflection, but it is so simple.
Especially with the Command pattern.
Because of the anonymous classes I could do it that way, and I really like the way to write code this way (I always did it with ActionListeners)
th.addMenuItem("Test",new Command(){
public void execute(){
//do stuff
}
});
Thank you :)

There is a better way to do this. This helps to hide the action done inside a command object. As you have to change the command, you don't have to mess with your other code.
Further, you can have a lot of different commands and they can be related by inheritance or aggregation or be injected into each other as needed AND NOBODY ELSE HAS TO KNOW.
First you have an interface:
public interface Command {
void execute();
}
Then you have your code take one of these:
console.registerCommand(Command command);
Then you write various classes that implement the interface and do something:
public class OneCommand implements Command {
public void execute() {
theObject.theMethod(theCommand); // calls what you would have with reflection
}
}
This is the standard GOF Command Pattern and you can read more about it here: LINK TO WIKIPEDIA
Note that this pattern, along with the other GOF patterns, were published in a book in 1994. The authors collected these best practices over many software projects. That book is in its 40th printing (according to Wikipedia).
All this suggests that lots of people have found lots of reasons to use these over many pieces of softwear, over many years and in many programming languages and systems.
It doesn't mean you need to always use them but use of a tried and tested pattern will help avoid unseen pitfalls.

Related

Java command Storage

Yes, this question is for a bot, but it requires little knowledge of bots. So please, don't be put off by that.
This question may seem similar to other PircBot questions, but bear with me, it isn't.
So, I've recently been working on an IRC bot based off of PircBot, and I've come upon a snag. I have a rapidly growing command list, and currently I'm using a horribly inefficient and very ugly block of these:
if(message.equalsIgnoreCase("!thatcommand"))
processMessage(channel,"returnforthatcommand"+sender);
I have a huge block of these where it just checks the message time after time for if it matches. That's my main problem. The process message method just sends the message after checking if I'm running the logger (printing the message to the console).
What I really want to do is to streamline it. I want to make some sort of chart, like a HashMap, that will process the strings accordingly. I've also considered making a Command class that stores the response and a boolean that tells whether or not a chatter has to be "opped" to use it. I've tried making files and started making a few attempts at HashMaps, but I could really use some direction on the simplest and/or most efficient way to go about this. I do have a few different "modes" for the bot, so making separate HashMaps for different privilege levels may be a good option.
One last thing: I later want to put the bot into a Jar file with a GUI for outside running (Eclipse takes ages to start up on this laptop), and I want to be able to make permanent changes to the command list through the bot itself as opposed to recoding it... That's why I was considering trying to reference a file, but then I had tons of problems with the program not being able to find said file.
Any suggestions?
Alright, for the people that don't like reading long things: I have sets of data that are called by a trigger String (message) and return a certain response String. How can I store these and call them in the simplest fashion, and how can I make it so that I can write things onto the list on the fly?
You could the use the Abstract Factory design pattern. It would be something like this:
public abstract class CommandFactory {
private static Map<String,Command> commands;
public static Command getInstance(String commandName) {
if (commands == null) initialize();
return commands.get(commandName);
}
private static void initialize() {
commands.put("commandA", new CommandA());
commands.put("commandB", new CommandB());
}
}
And write CommandFactory.getInstance("commandString") in the place of your if clauses.
Suggestion: Hashtable of objects implementing an interface which includes a method such as execute(). Use the hashtable to go from command to object, call its execute, done.
Yes, you'll need to initialize that table as your server starts up. Whether you do that from literal strings or have each actor announce its own keyword is up to you. The latter's probably more elegant but doesn't permit aliases.

When to Stop Defining FindBy's in the Object and Move Them to the Test

So I have an interesting conundrum I was curious to get some feedback from other Webdriver framework architects. Currently I follow a pretty standard execution model:
baseobject
pageobject (extends baseobject)
Junit testobject (references one or multiple pageobjects)
Within my pageobjects I chose to define my findBy UI mappings as variables, and in-turn reference them within the various methods I write for that pageobject. I find this works very well. However, one item I am waffling on is how to handle method design for pages (and their respective pageobject) when there exist potentially 50 separate hyperlinks.
My inclination and design thus far has been to create methods (I think of them as services really) for each link on most pageobjects I've created so that #Test I can simply call the method I want and be done with it. This eliminates the potential for test maintenance...standard practice I know. But I am now trying to decide...does it make sense to create 50 methods, one for each link for a page object, or do I go against my wishes and pass in linktext from the test itself, feeding into a single method that builds the findBy using that passed in parameter.
On one hand there is way less code within the pageobject, but on the other, tests become more brittle. There is potential for these links to be references in hundreds of tests.
Here is a brief example of my model:
classname extends baseobject{
By someLocator = By.linkText("some text");
By someOtherLocator = By.linkText("some other text");
By andAnotherLocator = By.id("someid");
public void someLinkMethod(){
driver.findElement(someLocator).click();
}
public void someOtherLinkMethod(){
driver.findElement(someOtherLocator).click();
}
public void someidMethod(){
driver.findElement(andAnotherLocator).click();
}
}
Thus we come to the end of the question. This model works great for test design. My services (methods) are insulated and easily maintainable. But what would I do if there were 50 UI mappings for links instead of 2 as I have shown above? I toyed with the following design, but really dislike it #Test:
public void selectFromLeftBar(String barItem){
driver.findElement(by.linkText(barItem)).click();
}
Any thoughts would be greatly appreciated!
Do it in your page object class. Here are the reasons:
What does your code do if your page changes the link text? You have to go into each test and change that text, even if the link does the same thing.
What happens if your page removes that link? You are stuck with the same problem, namely, having to find each time you call that link. If its a method...then you delete the method, and your IDE notifies you of each instance that you used it.
Finally, you are providing a standard interface for the test. If you make an exception here, what would stop you from passing other things into your page?
As a side note, I would recommend only mapping elements that you are going to use. I've found that if I map out every element I could possibly ever need then I end up with a massive class filled with fluff and less time on my hands.

According to basic oop conventions, should the menu code be in the main method or in a class?

I'm a student and I'm new to Java, this assignment I am doing is the first assignment I have to do that has to strictly follow oop conventions. So this may be a newb question. When coding a menu, would it be appropriate to put the menu code in the main method or should it be in a class and instantiated along with everything else?
EDIT:
The menu menu is a simple command line menu that is inputed with numbers, no gui. Not that far yet.
If you want to strictly follow the OOP convention you could have your own class like
abstract class MenuItem {
int index;
protected MenuItem(int index) {
this.index = index;
}
abstract void action();
}
class ExitMenuItem {
ExitMenuItem() {
super(3); // the index value of the menu item
}
void action() {
System.exit(0);
}
}
So that you can have a subclass specific for every menu item that has its behavior.
Then you could have a menu container, something like:
class Menu {
ArrayList<MenuItem> items;
void executeAction(String input) {
..
}
}
that should understand which voice has been chosen according to the stdin input and execute it. Of course you can enrich everything by having a default text for every menu item and whatever. Then in your main method you just instantiate the menu and take care of forwarding stdin input to it.
Mind that this is usually overkill in a simple menu but if you want to understand OOP then it's a nice way to go.
For a Object-Oriented approach, you should create the menu in the specific class. Main method is a legacy of Procedural/Imperative programming languages. Main method should just run the main thread.
It depends. That's usually the worst answer one can provide, but unfortunately, it fits perfectly.
You haven't provided the full requirements so it is a little difficult to guess what you are intending. Is this menu specific to a single class? Can it be run multiple times? Should it be able to be run in parallel?
Or rather, is this menu just an entry point into the actual program? ex: press 1 to login, press 2 to display something on screen, press 3 for ....
The reason I am giving you these questions is because they will shape the structure of your code. In the first case, if they are menus related specifically to a class and can be run from multiple locations in the code at multiple points, then it would make sense that the belong within the class structure itself (non static).
However, if the menu is purely an entry point into the application, it would make sense to either put them in the main() section of the code, or code another static method called menu() for clarity. But realistically, the menu() method would only get called from the main.
The next thing to ask yourself is how you plan to validate the responses from the menu selection. Do you need complicated/involved code? Does it make more sense for the validation routines to be part of the main method or have their own methods? Does it make more sense to have member variables to communicate between method class to validate, etc?
Keep in mind that static methods can be called without instantiating the class. That being said, a static main() method or static menu() method still remain within the class itself, and are part of OOP design.
Ask yourself this - if putting codes that prints menu in the main method, how do I handle printing multiple times?
If putting codes into methods in the same class as the main and I need to print menu somewhere else probably in another main class, how do I handle that?
Eventually, you will have a class that handles code dealing with displaying of menu, and the main class would only be calling on methods of that class. :)
Probably there are different tastes to this, and a good answer might also depend on what your app is doing.
First, for a small application I wouldn't mind having the menu in the main class.
But then for nice structure, it is a good idea to have a class that is responsible for printing the line-based menu and then of course also for reading the user input and invoking the action the user asks for. I think a good idea would be to call such a class Controller or Dispatcher. This class would be a singleton. Further I would think it's a good idea
to have a method displayMenu and dispatch. Both would be called from the constructor consecutively.
How dispatch is then calling the appriopriate action will depend on the rest of your app.
Some people don't like this style, as your main routine will probably have declarations only.

The correct way to pass a function as a string

Please allow me to explain what I am trying to do - I think that the title explains it roughly, but I am none too sure that I am going about things the right way, so please correct me if I am wrong!
I have created a custom dialog using a LayeredPane. Essentially a jPanel is shown on the POPUP_LAYER, thus appearing over the top of the main content. This panel contains a simple 'label-textbox-okay-cancel' group of controls. I will call this the 'Dialog Panel'.
What am I trying to do:
When a button is clicked on the main window (contained within the LayeredPane), the Dialog Panel will appear and allow the user to enter some text, then click okay or cancel. This is all easy enough, but I would like this code to be re-usable, which means that other buttons on the main window will invoke the same Dialog Panel, but with different text in the label.
This of course requires me to include some kind of callback function so that the okay button on the Dialog Panel will run the correct code, according to the button which invoked it.
My current attempt is to store a string which will contain the name of the function that should be run when the user clicks the okay button on the Dialog Panel. I am attempting to retrieve this string and convert it into the function name and so far I have found many references to 'Reflection', many of them suggesting that it is not a good idea.
In any case I have been unable to get any example code to work because I do not understand what the 'obj' is in the code below and am unable to invoke the method:
method = obj.getClass().getMethod(myCallbackString);
My questions are:
Firstly, am I even going about this the right way? I am more than open to suggestions, but please try to keep it as simple as possible because I really am just getting started!
Secondly, what is the 'obj' in the code shown above? I would really like to know, even if this is not the way that I should be doing things!
My other thoughts include: Should my Dialog Panel be in its own class, and if so, again, how to pass the callback function?
Any help or advice would be gratefully received.
BTW: In answer to the question "why not use a normal dialog?" I can only say that I am currently experimenting, and I simply want to see if I can do this!
MVK
The usual way the callback functions are passed in by Java programs is by passing instances of interfaces that implement a specific callback function. It is typical, though not required, to implement the interface anonymously.
For example, here is an interface:
interface MyCallback {
void performCallback();
}
Here is the way you define your dialog's method that takes a callback:
void openWithCallback(MyCallback cb) {
// Do something useful...
...
// Perform the callback
cb.performCallback();
}
Here is the way that you invoke that method:
public void OpenDialog() {
myDialog.openWithCallback(new MyCallback() {
public void performCallback() {
System.out.println("Inside callback...");
}
});
}
obj names the object whose method you want to call, in your case you can probably replace it with this (or drop it out entirely, since this is implied):
private void callByName(String name) {
try { getClass().getMethod(name).invoke(this); }
catch (RuntimeException e) { throw e; }
catch (Exception e) { throw new RuntimeException(e); }
}
For this to work you need to declare a public no-arg method with the appropriate name.
I think your idea is valid, although it has a major drawback: you store the method names as simple strings in your code, so the compiler can't check them for validity. Therefore, if you change the name of a method, you manually have to make sure you have updated all the strings referencing it.
This is what's usually meant with 'reflection is a bad idea'.
obj in your code is the object on which you want to call a method. As a simple example, the equivalent of someInteger.toString(); with reflection would be someInteger.getClass().getMethod("toString").invoke();.
On a more generic note, once you're comfortable with Java, you might also check out a functional language like Scala, where functions are regular objects, and the scenario you intend could be implemented with full compiler checking.
I think that you're making this way more complicated than it has to be. You said you want this:
This is all easy enough, but I would like this code to be re-usable, which means
that other buttons on the main window will invoke the same Dialog Panel, but with
different text in the label.
A DialogBox is, by definition, reusable. Why don't you just have the button click listener pass the appropriate text to the dialog box when clicked, so it shows the correct information?
If you need specific actions to happen after a button click on the dialog depending on the invoker, you may want to consider:
Created a custom DialogBox extension that includes logic that knows what to do based on who called it. Then when a button invokes the custom dialog, it would pass it a parameter to let it know what it wants to do after the dialog box is dismissed.
Look into using something like the abstract factory pattern.
Yes, you could do this via reflection. Yes, it would be a very bad idea, for many reasons that other people have discussed in other answers, especially if this is production code (though you seem to indicate it's an experiment.)
If you really just want to see how to work it with reflection, you'll probably want to read up on that topic. I found this to be one of the better tutorials out there.
I haven't worked with JPanel, but what I understand form your query, answer seems rather simple. Instead of passing method name, why dont you work on interface and pass the different implementation of that interface?

Correct way to use Actions to create menus, toolbars, and other components in Java

The naive way of writing building a menu in a Java Swing app is to do something like:
JMenu fileMenu = new JMenu("File");
JMenuItem openItem = new JMenuItem("Open...");
openItem.addActionListener(new ActionListener() { /* action listener stuff */ } )
fileMenu.addMenuItem(openItem);
A more experienced developer will recognize that actions can be accessed through a variety of mechanisms - menus, toolbar buttons, maybe even other workflows in the system. That person is more likely to write:
Action openAction = new AbstractAction();
openAction.setName("Open...");
openAction.addActionListener(new ActionListener() { /* action listener stuff */ } )
...
JMenuItem openItem = new JMenuItem(openAction);
My question is, what is the best way to manage these Action objects so they can be used across menus, toolbars, etc?
Create a factory class that returns specific actions?
Declare all of the actions as private static final Action in some utility class?
Take advantage of a Java application framework?
Something else?
Applications that I have developed that need to use that same actions across menus, toolbars, and other buttons have been done using Swing Application Framework.
Swing Application Framework
This framework will allow you to have a resource file where you can define all menu text, tooltips, and ICONS. I think the icons are the key, you do not have to load them yourself. Also, if you have any actions that you need to enable/disable you can override the method to control its state.
The website is worth the read.
You can group all your abstractAction using the dedicated Map javax.swing.actionmap .
See http://java.sun.com/javase/6/docs/api/javax/swing/ActionMap.html
Moreover each JComponent has an internal actionMap (getActionMap()).
class MyComponent
extends JPanel
{
public static final String ACTION_NAME1="my.action.1";
public MyComponent()
{
AbstractAction action= new AbstractAction() { ... }
getActionMap().put(ACTION_NAME1,action);
...
menu.add(getActionMap().get(ACTION_NAME1));
}
}
Hope it helps
Action is a bad abstraction - an ActionListener welded to a poor man's Map.
Certainly do not assign them to a static as they are mutable and also need some context to operate usefully.
My general advice for GUI programming is to note that it is actually much the same as any other area of programming. Follow the usual good practices. Notably, layering, separation of concerns, use (implementation) inheritance rarely and don't write a big ball of mud.
Also see this question, which is pretty much the same as what you're asking.
Create a base action for your application; this will help you IMMENSELY later on
Do create actions as you have in your code, instead favor subclasses of your base action
To organize them, it will depend on what you are doing with them, and you may have some actions organized one way and others created a different way. It will all depend.
What you want is to have a consistent way to locate/create an action in your code.
Depending on your UI, you may need to differentiate between "static" actions (i.e. stuff that's always available in your app, such as the menu system) and dynamic actions that are created only on certain screens or in certain locations.
In any case, using concrete subclasses of your specialized base action will help you keep these things organized. What you don't want is to be specifying things like labels, mnemonics, and icons all over the place in your code.
Edit: I got the feeling people didn't believe this was possible or easy, so I did it--took about an hour from scratch--would have taken 40 mins if I'd just used a single method as a target instead of reflecting it out to separate methods for each menu item.
Here's the Tested source code. It works, but is one big method and ugly--refactor it if you use it. I may fix it up a little over the next few days, I've always wanted to have a copy of this to keep around to reuse.
--- original post
First of all, remember to separate your code from data. That means you should NEVER type:
new Menu("File...");
The string "File..." is data. If you start thinking this way, you will find that your question answers itself.
First you need to build up some data. You need to get "File..." and "Save" into menus. I generally start off with a string array (which you can easily move to a file)
new String[]{"File...","+Save","Load"...}
This is one of the simpler patterns I've started out with. Then you can parse out the + sign and use it to mean "Drop down a level in the menu when you add this one"
This is just a silly convention, invent your own if you don't like it.
The next step is binding that to code to run. You could have them all call the same method, but what a pain in the ass (Giant switch statement). One possibility is to use reflection to bind a method name while you are reading in the data. Here's one solution (again it might not fit your tastes)
new String[]{"File...[fileMenu]","+Save[saveMenu]","Load[loadMenu]"...}
Then you parse out the thing in square braces, reflectively hook it up to a method in your current class and you are set.
There is a temptation I ALWAYS have at this point, and I've learned to fight it because it NEVER works out. The temptation is to use the first set of data ("File...") and manipulate it to fit some pattern and auomatically bind to your code (in this case, remove all non-alpha chars, make the first letter lower case and append "Menu" to get the correct method name). Feel free to try this, it's very attractive and seems slick, but be ready to abandon it when it doesn't meet some need (such as two menu items with the exact same name in different sub-menus).
Another way would be if your language supports closures, then you could actually create the file name and closure in the same place..
Anyway, once you start coding like this, you'll find that ALL your menu construction is in a single 10 line method and you can alter it to suit your needs. I had a case where I had to change a set of menus to a button hierarchy and I did it in 2 minutes.
In the end, you can use this pattern to set up the action objects easily and change how they are used easily (in a single location, single line of code), so you experiment with them. There are many ways to use them, but if you don't do what I'm recommending here, you will end up having to re-implement across every menu item for every change, which is really annoying--after a single change you will have wasted more time than if you had just implemented a data-driven solution in the first place.
This really isn't hard code, should take like an hour or two then you never have to write new Menu("... again. Trust me, this kind of tooling is just about always worth it.
edit:
I just about always code data-driven these days. Usually I'll prototype a few things the normal way, recognize the pattern and refactor--and if you are refactoring correctly, the data just about always factors out and what you're left with is beautiful, tight and maintainable.
I could do what I suggested above in less than 1/2 an hour (maybe an hour to do the reflective version). This is almost always just as long as it would do to use the unfactored version, and from then on, your savings multiply for every change.
This is very similar to what people like about ruby, except with ruby they seem to insert even more data into their code (which makes it awfully hard to extract your data from the code completely, which is always a nice goal for internationalization).
Hmm, did I mention that if you're good at extracting your data like this, i18n is virtually free?
I suggest you just give it a try sometime and see what you think. Embedding the control in the strings is unnecessary if it makes you uncomfortable. I tend to use string/object arrays just because they are really easy to enter, are still in the file while you are coding and are trivial to externalize later, but if you like YML or XML or properties files, use whatever you're comfortable with--just abstract your data from your code!

Categories

Resources