Feb 16, 2011
>Eek! if..then..else spaghetti ahoy!! Imagine you have 100 types of user, and the menu is dependent on the permissions that user >has....
>You have options here. Firstly, you can use a pattern - you can use a different patterns to achieve the same goal (creational patterns >are only easier or harder and less flexible) - Have a look at the visitor pattern http://www.dofactory.com/Patterns /PatternVisitor.aspx which is often used in menu type scenarios. But you should look at taking the responsibility for creating the menu >away from the "application" code
>delegate the responsibility at runtime via Dependency Injection. This will allow your application to call against an interface rather than a >concrete implementation. This class may itself use your pattern of choice.
>The key thing here Milovan, is context. "Do I need my MenuCreator class to be flexible enough that I can change how it works without >breaking anything else". There is no right answer, only what is suitable for the context.
Thank you very much for your reply ... Your answer has been very helpful ...
After a Google search and readings GoF book (and a few other books), I have made one solution based on Factory pattern.
Here is a short description:
interface IBaseMenu; // has a method: MenuStrip CustomMenu();
Classes, which implements interface IBaseMenu:
class Menu_UserType_1 : IBaseMenu
class Menu_UserType_2 : IBaseMenu, etc.
These classes implements method: CustomMenu():
- creates objects of type: MenuStrip, MenuStripItems, ..., and returns created MenuStrip (according to the type of logged user),
Class: MenuStripFactory // this class create objects of type IBaseMenu, on the base of logged user
public IBaseMenu getMenu(int userType)
IBaseMenu menuBase = null;
menuBase = new Menu_UserType_1();
menuBase = new Menu_UserType_2();
throw new Exception("Unknown Object");
Finally, in MainForm, the code is:
MenuStripFactory menuFactory = new MenuStripFactory();
IBaseMenu menuBase = menuFactory.getMenu(UserType_XY);
this.MainMenuStrip = (MenuStrip)menuBase.CustomMenu();
It works fine.
Now, I'd like to add MenuItemsClick handlers - could I continue with Factory pattern or try to do it with some new pattern?
Thanks again for your reply ...
Feb 15, 2011
My humble thoughts..
Whenever we have a scenario of parsing set of rules and render different group of items (UI components like menus) to UI layer.. Builder Pattern may be the best suite.
1) On login you you call the Director class which may take UserInfo Object as parameter.
Menuitems menuItems = Director.BuildMenu(new UserInfo(UserId)); //for simplicity assumed to pass only User Id
2) The Director class here acts like a stub for creating Rule based UI objects, which may stay in the UI layer.
3) On Receivng the Build Menu request from Windows Form, will choose the respective Builder object , here the Menu Builder
4) Then passed on the UserInfo obejct to the MenuBuilder
5) Menu Builder which may be in a different layer will need to parse through set of rules , Like verifying the DB table to get access rights for the current user.
5) Build list of Menu Items based on the data retrieved from DB.
6) Because its Winforms application you may wish to have a Command Type Object (as a Member) in each menu item ,
which could be initialized to store the respective action.
7) Return the list to the Director Class and it in turn -returns to the Windows Forms.
Hope this helps.
Tarriq Ferrose Khan.
Feb 06, 2011
I think the Strategy Pattern is better than State Pattern here.
My question is why do you think you want to preserve State (as in the State pattern)?