Some of the reasons you might want a GUI are:
- Some, or all, of the users are not comfortable with the command line interface
- It may be easier to use a GUI, due to the complexity of the application. Think about Adobe Illustrator, the GUI is much simpler than writing postscript files or similar
- There are visualizations, graphs and similar things that are better in a GUI than in ASCII
I suspect that the main thing that would motivate you, based on your description, is the first one. If you have some users that aren't comfortable with the command line interface, then you may want to provide a GUI.
One thing to consider, there are a few applications I have used that basically build their GUI as a front end for the command line version, so there is a lot of shared code.
I think you've confused having an interface for your program to call to add/remove items for a particular player and being able to manage all individual cases. The interface to the rest of your program should remain simple. By simple I mean it should be single-purpose and the only methods public will be those that will be called.
As I understand it, it is PlayerItemStorage
that handles the logic about fitting and physical layout of those items. This sort of complication should remain within PlayerItemStorage. For the callers of PlayerItemStorage
, they should only care about what items are present, if an item has been removed or added. When this happens, through a PlayerItemStorageChangeHandler
interface, any instance in your program that wants to know about this event can register. Your PlayerStorageContainer
would use this as a means to get this information and act consequently.
Any validation about whether or not they can fit it in storage should be entirely managed by PlayerItemStorage
. Notice that I said that whether or not an item has been removed or added should be handled by PlayerItemStorage
. Do not be tempted to put the logic in PlayerStorageContainer
since it should not know whether or not it is possible.
Granted, I still think adding and removing items from PlayerStorageContainer
should be possible, however you should allow the possibility of failure. Anything that you would want to happen as a consequence of adding it to PlayerItemStorage
should be put in the same place as your PlayerItemStorageChangeHandler
listener for new adds/removes (again, avoiding to duplicate your code). Also, I presume that the main interface to be called when a player adds/removes items to his storage should be PlayerItemStorage
and not PlayerStorageContainer
for most operations, however I suppose if you say wanted to add a gift item to a player's storage, it would be preferable not to care which storage it is (just throw it anywhere where there's room).
Once you've established this relationship, you'll see that a bank concept with tabs is nothing more than a collection of PlayerItemStorage
. I would therefore create a special type of PlayerItemStorage
called PlayerBankItemStorage
. It would override the same operations called by PlayerStorageContainer
, but it could also maintain open tab state. Try to keep the logic simple though. You should forward most calls to PlayerItemStorage
. PlayerBankItemStorage
would listen to PlayerItemStorageChangeHandler
and then throw the event itself (if it should handle events at least, otherwise adding a new listener should simply forward to each individual PlayerItemStorage
.
The key thing to remember is to avoid duplicating logic. Keep class roles clear in your mind, and you'll find that it is easier to delegate tasks to your classes and keep logic in one place only.
Best Answer
if you want OO I suggest a Menu interface with methods to write out the options and parsing the input and returning the next Menu
so your main loop becomes: