views:

193

answers:

3

The object here is to update the UI. I normally do this on the client however this application uses the code behind. Anyways my question is I am trying to clean up these if else statements and I thought the strategy pattern may be appropriate. I don't need everything done for me but if you could give me a couple pointers to get going. Do I create an interface first and then each strategy implement the interface? Are generics helpful here? What types of methods should be in the interface? Any thing to get me going would be very much appreciated.

if (someObject.Status == 'A') {
                    btnRecordCall.Enabled = false;
                    btnAddMailOrStatusAction.Enabled = false;
                    btnPayments.Enabled = false;
                    btnAddressMaint.Enabled = false;
                    btnFilter.Enabled = false;
                    btnAddCoverage.Enabled = false;
                    btnPolicyForms.Enabled = false;
                    lblIsArchived.Text = "********** THIS CLAIM HAS BEEN ARCHIVED **********";
                } else if (someObject.Status == 'D') {
                    btnRecordCall.Enabled = false;
                    btnAddMailOrStatusAction.Enabled = false;
                    btnPayments.Enabled = false;
                    btnAddressMaint.Enabled = false;
                    btnFilter.Enabled = false;
                    btnAddCoverage.Enabled = false;
                    btnPolicyForms.Enabled = false;
                    lblIsArchived.Text = "- De-archive Request Pending";
                } else {
                    btnRecordCall.Enabled = true;
                    btnAddMailOrStatusAction.Enabled = true;
                    btnPayments.Enabled = true;
                    btnAddressMaint.Enabled = true;
                    btnFilter.Enabled = true;
                    btnAddCoverage.Enabled = true;
                    btnPolicyForms.Enabled = true;
                    lblIsArchived.Text = "";
                }

Thanks, ~ck

+2  A: 

Well first of all, if you're going to use the Strategy pattern with an Interface you might want an interface like this.

public interface IStrategyUI
{
   void Execute();
}

then a few classes for your logic

public class StatusAStrategy : IStrategyUI
{
  public void Execute()
   {
      //implement
   }
}

then your if statement can be a factory technically.

IStrategyUI logic;

switch(someObject.Status)
{
    case 'A':   logic = new StatusAStrategy();
            //etc etc

}

logic.Execute();

or you can return this object as an interface and encapsulate the switch statement in another method or factory class.

So that you can use it like this.

IStrategyUI logic = StrategyFactory.GetStrategy(status);
logic.Execute();

It's up to you.

Also I am not using a containment class here, but you can if you want to.

You can also do this with delegates.

Containment class

 class StrategyHolder
    {
        public Action Strategy { get; set; }

        public void Execute()
        {
            if(this.Strategy != null)
                 this.Strategy();
        }
    }

Different strategy Methods.

void EnableStatusA()
{
   //do everything for status A
}

Switch statement

StrategyHolder logic = new StrategyHolder();

switch(someObject.Status)
    {
        case 'A':   logic.Strategy = EnableStatusA;
                //etc etc

    }

return logic;

Call this from outside.

StrategyHolder logic = StrategyFactory.GetStrategy(status);
logic.Execute();
Stan R.
Thank you Stan. In the execute method in the implementations, how do I get references to the page controls? Do I pass a refernces to the page and do a findcontrol('someId')? or is there a better way?
Hcabnettek
Yes, you can pass a reference to the page itself, and then do the same thing you were doing before i.e. page.lblIsArchived.Text = ""; etc..You can pass the reference to the Page in the constructor or in Execute method. its up to you.
Stan R.
+3  A: 

If all the buttons get the same enabling regardless of the status, as in your example, then I'd hide that away in a list of buttons and just iterate over them. Then your parameters for the strategy boil down to a single boolean and a string - and it's pretty easy to do that anywhichway. If there's greater complexity to it, then different classes implementing an interface that sets the controls would be in order, possibly with an abstract superclass that holds the overall logic.

Carl Manaster
Thank you Carl.
Hcabnettek
A: 

I think what you are looking for is the State patten. This is similar to the strategy pattern except that each state object is normally given a reference to the context object (in your case this is the form) when it is created. This allows the different states to do things to the context object in response to events.

When implementing a state pattern is is often preferable to make each seperate state inherit from an abstract base class. The base class can then implement the default operations in virtual methods and then you only have to override the operations that differ for each state.

public interface IFormState
{
    void EnableDisableControls();
}

public class DefaultState : IFormState
{
    private MyForm context;

    public DefaultState(MyForm context)
    {
        this.context = context;
    }

    protected MyForm Context
    {
        get
        {
            return this.context;
        }
    }

    public virtual void EnableDisableControls()
    {
        this.context.btnRecordCall.Enabled = true;
        this.context.btnAddMailOrStatusAction.Enabled = true;
        this.context.btnPayments.Enabled = true;
        this.context.btnAddressMaint.Enabled = true;
        this.context.btnFilter.Enabled = true;
        this.context.btnAddCoverage.Enabled = true;
        this.context.btnPolicyForms.Enabled = true;
        this.context.lblIsArchived.Text = "";
    }
}

public class StateA : DefaultState
{
    public StateA(MyForm context)
        : base(context)
    {
    }

    public override void EnableDisableControls()
    {
        base.EnableDisableControls();

        this.Context.lblIsArchived.Text = "********** THIS CLAIM HAS BEEN ARCHIVED **********";
        // etc...
    }
}
Martin Brown