В стратегической модели может стратегия брать Контекст в качестве параметра


Сводка обратной связи

Я теперь закрою этот thead (я думаю, что больше не будет обратной связи), и попытайтесь суммировать то, что я понял

  1. использование "Контекста" в качестве параметра для моей стратегии представляет плотное соединение, которого нужно избежать и также могло вынудить меня выставить свойства, которые должны, возможно, остаться скрытыми в классе.
  2. Для уменьшения связи было бы лучше обеспечить необходимые значения или по крайней мере использовать интерфейс вместо конкретного типа к стратегии.

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

Давайте возьмем следующую классическую реализацию

//The strategy
interface IStrategy  
{  
  void Execute();  
}  

class ConcreteStrategyA : IStrategy
{
  public void Execute()
  {
    Console.WriteLine( "Called ConcreteStrategyA.Execute()" );
  }
}

class ConcreteStrategyB : IStrategy
{
  public void Execute()
  {
    Console.WriteLine( "Called ConcreteStrategyB.Execute()" );
  }
}

//The context
class Context
{
  IStrategy strategy;

  // Constructor
  public Context(IStrategy strategy)
  {
    this.strategy = strategy;
  }

  public void UpdateContext(IStrategy strategy)
  {
    this.strategy = strategy;
  }

  public void Execute()
  {
    strategy.Execute();
  }
}

Все примеры, которые я видел, имеют довольно простые стратегии, которые берут основные аргументы (целые числа, например). То, что я хотел бы знать, - то, если существует что-то не так, если стратегия использует Контекст, чтобы сделать работу.

Это дало бы что-то как

//The strategy
interface IStrategy  
{  
  void Execute(Context arg);  
}  

и вызов дал бы

//The context
class Context
{
  ....

  public void Execute()
  {
    strategy.Execute(this);
  }
}

Это "Связывается", чтобы избежаться? Это в порядке?

10
задан FrenchData 15 January 2010 в 12:04
поделиться

3 ответа

Одна проблема, которую я вижу в вашем подходе, заключается в том, что существует тесная связь между конкретным классом Context и экземплярами классов стратегии. Это означало бы, что классы стратегии могут использоваться только с классом контекста. Один из способов обойти это - сделать классы стратегии зависимыми (или использовать) интерфейс, который реализует класс «Контекст».

ИЗМЕНИТЬ Также, когда классы стратегии имеют экземпляр класса Context, эти классы должны явно получать данные из класса Context. Это означало бы добавление геттеров (при необходимости) в класс Context для классов стратегии, чтобы получить нужные им данные. Но добавление геттеров не обязательно является хорошей объектно-ориентированной практикой, поскольку большее количество геттеров создает риск нарушения инкапсуляции.

Вы можете придумать альтернативу: не передавать ссылку (this) класса Context методу (ам) в классе стратегии, а передать только необходимые данные в класс стратегии.

Например, если класс контекста выглядит примерно так: (код находится на Java)

Context {
   IStrategy strategy;
   List<Integer> scores;

   public Context(IStrategy strategy)
   {
        this.strategy = strategy;
        scores = new ArrayList<Integer>
   }

   public print() {
       strategy.sort(scores);
   }
}

public interface IStrategy<Integer> {
    public void sort(List<Integer> l);
}

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

7
ответ дан 3 December 2019 в 23:13
поделиться

IMHO, все в порядке, но я предпочитаю передавать контекст стратегии через конструктор класса реализации стратегии.

5
ответ дан 3 December 2019 в 23:13
поделиться

Твой код - это твой код, пиши все, что имеет для тебя смысл. Однако, у меня есть предостережение.

Цель шаблона стратегий - создать семейство стратегий, которые могут быть взаимозаменяемы. Как и многие другие шаблоны дизайна, он извлекает выгоду из развязки. В данном случае мы отделяем поведение от класса, который использует такое поведение.

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

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

2
ответ дан 3 December 2019 в 23:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: