重构帮助-策略模式

发布于 2024-07-27 15:47:17 字数 1697 浏览 10 评论 0原文

这里的目标是更新 UI。 我通常在客户端上执行此操作,但是此应用程序使用隐藏的代码。 无论如何,我的问题是我正在尝试清理这些 if else 语句,并且我认为策略模式可能是合适的。 我不需要为我做所有的事情,但如果你能给我一些指导,让我继续前进。 我是否要先创建一个接口,然后每个策略都实现该接口? 泛型在这里有用吗? 接口中应该包含哪些类型的方法? 任何能让我继续前进的事情都将非常感激。

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 = "";
                }

谢谢, 〜ck

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

日暮斜阳 2024-08-03 15:47:17

如果无论状态如何,所有按钮都获得相同的启用(如您的示例所示),那么我会将其隐藏在按钮列表中,然后迭代它们。 然后你的策略参数可以归结为一个布尔值和一个字符串——无论如何,做到这一点都很容易。 如果它的复杂性更大,那么实现设置控件的接口的不同类将是有序的,可能具有保存整体逻辑的抽象超类。

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.

我不在是我 2024-08-03 15:47:17

首先,如果您要将策略模式与接口一起使用,您可能需要这样的接口。

public interface IStrategyUI
{
   void Execute();
}

然后是你的逻辑的几个类

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

然后你的 if 语句在技术上可以是一个工厂。

IStrategyUI logic;

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

}

logic.Execute();

或者您可以将此对象作为接口返回,并将 switch 语句封装在另一个方法或工厂类中。

这样你就可以像这样使用它。

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

由你决定。

另外,我在这里没有使用收容类,但如果您愿意,也可以这样做。

您也可以与代表一起执行此操作。

遏制类

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

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

不同的策略方法。

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

Switch 语句

StrategyHolder logic = new StrategyHolder();

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

    }

return logic;

从外部调用此语句。

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

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();
↘紸啶 2024-08-03 15:47:17

我认为您正在寻找的是 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...
    }
}

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...
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文