Context Pattern?

 
50   50
Jun 28, 2010
 
Hi

I'm curious if there is a pattern that allows an object to change behavior based on context. I have looked at the State pattern, but would like to explain what i'm trying to do and see if there is maybe not a better way of achiving the same.

I am creating a webpage that loads menu items in a div on a page dynamically based on the context of the div. Each menu item is an object that I have created. Certain menu items are reused across different pages (example "add new") , but should behave differently on different divs.

For example:

I have an Abstract Employee class, and then Director Concrete Class, Manager Concrete Class ect.
I also have an Abstract MenuItem Class, and then AddNewMenuItem Concrete Class, RemoveMenuItem Concrete Class.

Both Concrete Employee classes loads AddNewMenuItem classes, but when the AddNewMenuItem is clicked, it should add a New Director or add a New Manager, based on the div it was loaded in.

What would be the best way to accomplish this?




66   95.6
Jun 30, 2010
I am not quite sure whether I understand your setup, but I get a sense it is a bit over-architected.

Why not give the base class of the Context (the Employee, Director, Manager) a virtual CreateMenus method and let each derived type implement this. Or, if you don't want to pollute the Context objects, build a static MenuFactory class with a Create method. Pass in the Context (in the Create method) and out comes a context-sentive list of menu items. 




50   50
Jul 01, 2010

Hi Ian, Thank you for replying

That is exactly what i am doing, I have a menuFactory that returns a list of context-sensitive menu items, the problem is still letting each menu item do something differently when clicked, based on the context.

For example

Loading an Employee would use the menuFactory to Load menu items ("Add","Remove","Refresh")

Loading a Director would use the menuFactory to Load menu items ("Add", "Remove", "Refresh", "Pay")

Loading a Manager would use the menuFactory to load menu items ("Add", "Remove", "Refresh", "Manage")

As you can see the menu items "Add", "Remove" and "Refresh" is common throughout all concrete classes.

Yet when I click on "Add", it needs to add an entity based on the concrete class
Employee's Add item should add an employee
Director's add item should add a director
Manager's add item should add a manager

So the challange i'm facing is making the AddMenuItem object, behave differently, based on context.


70   95.9
Jul 08, 2010
you can do it like this:
abstract a inerface contains all the actions in menus.
then create concrete class(Employee's /Director's and so on) implement this interface.
create a controller class,it has a interface container that could save the concrete class who implement the interface and has a method to set the current-menuaction.

70   95.9
Jul 08, 2010

these are the codes for my answer:
public interface IMenuAction
    {
        void Add();
        void Remove();
        //...
    }

    public class ManagerMenuAction : IMenuAction
    {

        #region IMenuAction 成员

        public void Add()
        {
            //Do something.
        }

        public void Remove()
        {
            //Do something.
        }

        #endregion
    }

    public class MenuActionController
    {
        Dictionary<string, IMenuAction> container = new Dictionary<string, IMenuAction>();
        IMenuAction _currentMenuAction;
        public IMenuAction GetCurrentMenuAction
        {
            get
            {
                return _currentMenuAction;
            }
        }

        public void AddMenuAction(string key, IMenuAction action)
        {
            if(!container.ContainsKey(key))
                container.Add(key, action);
        }

        public void SetCurrentMenuAction(string key)
        {
            _currentMenuAction = container[key];
        }
    }

    public class Invoker
    {
        MenuActionController _controller = new MenuActionController();
        public void Run()
        {
            IMenuAction action = new ManagerMenuAction();
            _controller.AddMenuAction("Manager", IMenuAction);
            //Add others
            _controller.SetCurrentMenuAction("Manager");
            //
            _controller.GetCurrentMenuAction.Add();
            _controller.GetCurrentMenuAction.Remove();
            //...
        }
    }