помощь рефактора - шаблон стратегии - PullRequest
2 голосов
/ 21 июля 2009

Целью здесь является обновление пользовательского интерфейса. Я обычно делаю это на клиенте, однако это приложение использует код позади. В любом случае, мой вопрос заключается в том, что я пытаюсь очистить эти утверждения 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 = "";
                }

Спасибо, ~ Ск

Ответы [ 3 ]

3 голосов
/ 21 июля 2009

Если все кнопки получают одинаковое включение независимо от статуса, как в вашем примере, то я бы скрыл это в списке кнопок и просто перебрал их. Тогда ваши параметры для стратегии сводятся к одному булевому значению и строке - и это довольно легко сделать в любом случае. Если есть большая сложность, то различные классы, реализующие интерфейс, который устанавливает элементы управления, будут в порядке, возможно, с абстрактным суперклассом, который содержит общую логику.

3 голосов
/ 21 июля 2009

Ну, во-первых, если вы собираетесь использовать шаблон «Стратегия» с интерфейсом, вам может потребоваться такой интерфейс.

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
}

Смена оператора

StrategyHolder logic = new StrategyHolder();

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

    }

return logic;

Позвоните этому извне.

StrategyHolder logic = StrategyFactory.GetStrategy(status);
logic.Execute();
0 голосов
/ 21 июля 2009

Я думаю, что вы ищете это State patten. Это похоже на шаблон стратегии, за исключением того, что каждому объекту состояния обычно дается ссылка на объект контекста (в вашем случае это форма) при его создании. Это позволяет различным состояниям что-то делать с объектом контекста в ответ на события.

При реализации шаблона состояний часто предпочтительно, чтобы каждое отдельное состояние наследовало от абстрактного базового класса. Базовый класс может затем реализовать операции по умолчанию в виртуальных методах, и тогда вам нужно только переопределить операции, которые отличаются для каждого состояния.

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...
    }
}
...