Реализация «запасных» классов

У меня есть набор классов, каждый из которых должен решить в какой-то момент, какой из двух или трех подходов они должны использовать внутри, чтобы реализовать ту же функциональность извне. В идеале это должно включать в себя резервные функции, при которых, если ApproachA терпит неудачу, он не сможет попытаться использовать ApproachB (и, возможно, приблизится к C, D и т. Д.). До сих пор я просто использовал код вроде if (! Success) {Код подходаB} . Проблема заключается в том, что несколько более поздних методов также должны знать, какой подход был выбран, и все они также разрабатывают свои собственные операторы if (MethodChosen) {} else {} . Я действительно хочу решить эту проблему с помощью чего-то менее громоздкого ... за исключением того, что ни один из других вариантов, которые я рассмотрел, не кажется таким уж "громоздким". Вот три подхода, о которых я подумал:

  1. Реализуйте статику. Create метод, который решает, какой из двух производных классов создать, если два класса имеют поддерживающий их интерфейс. Недостатком этого является то, что вы пишете много одного и того же кода дважды, и на самом деле это не создает «запасной вариант», так как заставляет принимать все решения заранее в методе .Create. Это должно сработать 9/10 раз, но будут и другие 1/10 раз, когда я хочу, чтобы откат срабатывал только тогда, когда основной попытался и потерпел неудачу.
  2. То же, что и выше, но с базовым или абстрактным задействованный класс либо в качестве вспомогательного для обоих, либо с основным классом в качестве базового для резервного. Это имеет тот же резервный недостаток, но, по крайней мере, там мало или совсем нет повторяющегося кода.
  3. Реализуйте обычно построенный абстрактный класс с дочерними классами, которые можно изменять во время выполнения: т.е. { если (какие-то условия) MyChild = ChildClassA; еще MyChild = ChildClassB; } public void Execute () { MyChild.Execute (); }

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

Что еще я должен учитывать?


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

Спасибо всем, кто помог с окончательным решением!

Для любопытных, мое окончательное решение работало примерно так:

  • Создать абстрактный класс Handler, примерно как описано в статье в Википедии, но с public abstract Handler GetHandler () , и добавление других абстрактных методов, таких как Load, Save и т. д.
  • Реализуйте подклассы частного обработчика для родительского класса (они также могут быть подклассами, поскольку они ' я буду обрабатывать вещи только для этого конкретного класса ... также избегает проблем с именованием в дальнейшем). Все дочерние классы принимают параметр типа родительского объекта в своем конструкторе, поэтому они имеют легкий доступ к данным родительского объекта.
  • В конструкторе родительского класса настройте цепочку обработчиков / преемников ответственности (опять же, как в примере ), затем вызовите FirstHandler.GetHandler (this) и сохраните результат, чтобы класс тогда знал, какой обработчик использовать в будущем.
  • Большинство обрабатываемых методов затем просто сокращаются до Handler.MethodName () .
5
задан RobinHood70 16 November 2010 в 02:14
поделиться