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.
-
please don't cross-post : stackoverflow.com/questions/40327748/… "Cross-posting is frowned upon as it leads to fragmented answers splattered all over the network..."gnat– gnat2016年10月30日 14:24:37 +00:00Commented Oct 30, 2016 at 14:24
-
Delete the cross post in SO. This is the correct site for this question since it is a design question.Tulains Córdova– Tulains Córdova2016年10月30日 17:10:23 +00:00Commented Oct 30, 2016 at 17:10
1 Answer 1
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 theexecute()
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:
Explore related questions
See similar questions with these tags.