Шаблон стратегии с различными параметрами в интерфейсе (C #) - PullRequest
6 голосов
/ 24 декабря 2009

Я в основном пытаюсь реализовать шаблон Стратегии, но я хочу передать различные параметры реализации "интерфейсов" (которые наследуются от одного и того же объекта) и не знаю, возможно ли это. Может быть, я выбираю неправильный шаблон, я получаю сообщение об ошибке, похожее на

«StrategyA» не реализует унаследованный абстрактный член «void DoSomething (BaseObject)»

с кодом ниже:

abstract class Strategy
{
 public abstract void DoSomething(BaseObject object);
}

class StrategyA : Strategy
{
 public override void DoSomething(ObjectA objectA)
 {
  // . . .
 }
}

class StrategyB : Strategy
{
 public override void DoSomething(ObjectB objectB)
 {
  // . . .
 }
}

abstract class BaseObject
{
}

class ObjectA : BaseObject
{
 // add to BaseObject
}

class ObjectB : BaseObject
{
 // add to BaseObject
}

class Context
{
   private Strategy _strategy;

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

    // i may lose addtions to BaseObject doing this "downcasting" anyways?
 public void ContextInterface(BaseObject obj) 
 {
  _strategy.DoSomething(obj);
 }

}

Ответы [ 5 ]

13 голосов
/ 24 декабря 2009

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

Кроме того, поскольку вы используете C #, я рекомендую прочитать статью Джудит Бишоп под названием Об эффективности шаблонов проектирования, реализованных в C # 3.0 . Это подробно описывает несколько подходов к шаблону посетителей и содержит некоторые интересные, полезные идеи.

6 голосов
/ 24 декабря 2009

В сигнатуре метода C # указывается его имя, список параметров типа и список формальных параметров. В приведенном выше коде «переопределения» имеют подписи, отличные от виртуального метода, и поэтому это не разрешено.

Основная идея, лежащая в основе Pattern Pattern, заключается в определении набора взаимозаменяемых алгоритмов, детали которых скрыты внутри. Но если ваши стратегии различаются (по типу) в том, что они могут принять в качестве входных данных, они больше не являются взаимозаменяемыми. Таким образом, кажется, что это неправильный шаблон для использования в этой ситуации.

4 голосов
/ 21 сентября 2011

Вы можете рассмотреть эту статью: http://hillside.net/plop/2010/papers/sobajic.pdf Шаблон называется «шаблон параметризованной стратегии» и должен соответствовать тому, что вам нужно. По сути, он основывается на шаблоне стратегии и позволяет стратегиям (различным алгоритмам) иметь разные параметры. Параметры заключаются в специальные классы, то есть классы параметров. Каждая стратегия (то есть алгоритм) должна реализовывать метод GetParameters (), который отправляет обратно список экземпляров parmaters для конкретного алгоритма.

2 голосов
/ 24 декабря 2009

Шаблон стратегии предназначен для обеспечения различного поведения входных объектов одного типа.

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

1 голос
/ 31 июля 2010

Вы можете создать класс параметров следующим образом:

public class Parameters
{
  public ObjectA {get; set;}
  public ObjectB {get; set;}
}

Измените ваши методы для принятия таких параметров, как:

class StrategyA : Strategy
{
 public override void DoSomething(Parameters parameters)
 {
      //  Now use ObjectA
      if(parameters.ObjectA.SomeProperty == true)
      { ... }
 }
}

Таким образом, вы можете добавить дополнительные параметры, если ваши требования изменятся в будущем. Другой альтернативой является использование Dictionary<string, object>, где вы можете сделать:

class StrategyA : Strategy
{
     public override void DoSomething(Dictionary<string, object>parameters)
     {
          //  Now use ObjectA
          var someProperty = (bool)parameters["SomeProperty"];
          if() ...
     }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...