Java Design – How to Create a Menu for Easy Addition of New Options

designdesign-patternsjavaobject-orientedobject-oriented-design

I am trying to create a java console program which displays a Menu with few options. Each option selection performs some independent operation say executing a script or performing some db operation, for example:

1 option1title  
2 option2title  
3 option3title  
...  

I need to design this such that I should be able to add new options easily. say just by adding a new class.
Some options might show a submenu as well.

Design thoughts that I have

Have an interface say IOption with methods like optionTitle, optionAction. So each Option in the menu would implement this interface and write its action & title.

How do I display the menu ?
I can have a class which where each option is registered. Say a list of all the options. Then my main program would iterate over this classes and shows the menu. Option selection would call the action of that particular class.
Otherwise I can use reflection/annotation to get the all the classes which implement this interface and show the menu —-> This might be an overkill.

Is there any better way to design this ? Any design patterns that I can bring in ? My priority is good design.

With my solution also, if I want to add a new option, I would need to register each option in a list, implement the class etc.
Instead of adding to a list in register class, how about having the link between optionTitle and class info in an xml file or something ?

And I'll have submenus as well. Other than writing this in the itemAction method, any better way to design this ?

Let me know If I need to add more info.
Note: This will always be invoked from command prompt. Either shell/ windows command prompt. I don't need any GUI for this.

Best Answer

Proposed design:

You could use the command pattern:

  • A command interface defines the methods related to a menu option (i.e. command). The most important method here is optionAction() (corresponds to the execute() method of the pattern).
  • Concrete commands are classes that implement this interface : optionAction() is overridden to define the actions that shall be executed for a specific command.
  • When concrete commands are instantiated by a client (your main() ?), a reference to a receiver object is stored. That object will be used to execute the action later.
  • A specific concrete command class implements a menu loop as action. But instead of hard-coding every different submenu in its own class, use a single SubmenuCommand class, the instances of which will refer to a menu object that has a list of options (commands).
  • The invoker will execute the created commands when needed. In your case, you could simplify the invoker: your main() would somehow invoke the command corresponding to the toplevel menu. And this one would invoke the chosen commands.

Variants of this design:

The menu objects could be constructed during initialization. Typically, you'd use the builder pattern to initialize each menu programatically. Then it could make sense to use optionTitle().

However, you could also load the menu from a configuration file. In this case, the optionTitle() would be useless: you'd read that title from the configuration file (with flexibility to customize the text, and even possibility to localize/translate the menus). In principle you'd do that in the the director of the builder, but if you want also to configure other commands, a factory method pattern could be considered as well.

If you opt for the dynamically load of menus, there are a couple of delicate points to handle:

  • first you need to link you text of menus with command classes. Either you use reflection to identify the right classes by name, or -- much simpler -- you use a map that links keywords corresponding to commands to class specific factories (the map would be static, and initialized before the config file is parsed).
  • dependencies between menus: the simplest way would be to organize your menus in bottom up order, so to be sure that a menu is always loaded/created before it is referred to in other menus. Similarly to command classes, you'd also have a map of menus (the map would be dynamic, and populated as new menus are loaded : the menu structure could hence be totally dynamic and reconfigurable).

Wrap up:

Here a simplified class model that shows the general structure. I leave however the client, the invoker, the director and the builder out of this figure, as it depends very much on the rest of your application:

enter image description here

Related Topic