Можно отделить контекст (переключение дескрипции, параметры) от стратегии для решения запроса (входных данных) и его ответа (выходных данных).
Вы можете использовать, например, обобщенные элементы для решения этой проблемы в различных случаяхс одной кодовой базой.Например, стратегия определяется типом входных и выходных данных и условием оценки:
public class Strategy<TInput, TOutput>
{
public Predicate<TInput> Condition { get; private set; }
public Func<TInput, TOutput> Result { get; private set; }
public Strategy(Predicate<TInput> condition, Func<TInput, TOutput> result)
{
Condition = condition;
Result = result;
}
public TOutput Evaluate(TInput input)
{
return Condition(input) ? Result(input) : default(TOutput);
}
}
Контекст имеет разные стратегии и запрашивает стратегии на их ответственность (данные условия в порядке, можно рассчитать результатдля запроса).
public class Context<TInput, TOutput>
{
private List<Strategy<TInput, TOutput>> Strategies { get; set; }
public Context(params Strategy<TInput, TOutput>[] strategies)
{
Strategies = strategies.ToList();
}
public TOutput Evaluate(TInput input)
{
var result = default(TOutput);
foreach (var strategy in Strategies)
{
result = strategy.Evaluate(input);
if (!Equals(result, default(TOutput)))
break;
}
return result;
}
}
Давайте рассмотрим простой пример, в котором входная строка должна быть преобразована в выходную строку (например, в случае переключения).
1.Определите ваши действия (для упрощения это (как видите, у каждого метода есть своя логика и забота):
private static string Move(string s)
{
if (s == "move")
return "doMove"; // here could be some more action...
return null;
}
private static string Query(string s)
{
if (s == "point")
return "queryPoint"; // here could be some more action...
return null;
}
2. Определите условие для запускаоценка (например, CanExecute of ICommand):
private static bool Condition(string s)
{
return !string.IsNullOrEmpty(s); // could eval different states, values
}
... вы могли бы даже определить больше условий (например, одну функцию оценки условий на стратегию), но мы используем здесь только одно.
3. Создайте объекты стратегии , требуемые контекстом (они символизируют различные пути коммутатора и дают нам результат):
var navigate = new Strategy<string, string>(Condition, Move);
var query = new Strategy<string, string>(Condition, Query);
2. Инициализируйте ваш контекст (представляет корпус переключателя со входом):
var strategies = new List<Strategy<string, string>> {navigate, query};
var context = new Context<string, string>(strategies.ToArray());
3. Подключите их к коду (например, выполните «переключатель» нажатием кнопки):
private void ButtonClick(object sender, RoutedEventArgs e)
{
var message = context.Evaluate(textBox1.Text);
if (message != null) MessageBox.Show(message); // display result
}
... вот и все.
Контекст дает вам правильную стратегию (может выполнять правильные действия или предоставлять «инструменты», необходимые для выполнения некоторых действий (например, ICommand).