Шаблон, где только один обработчик из многих должен действовать на основе специализации - PullRequest
2 голосов
/ 11 октября 2010

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

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

Хотя оба типа A и B могут справиться с этим, B был разработан специально для этой ситуации и являетсяправильный выбор.

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

Я подумываю об использовании шаблона Chain of Responsibility , чтобы разорвать эту связь.Однако я не вижу способа обеспечить выполнение наиболее квалифицированной реализации .Если я передам это реализациям, чтобы сделать это определение, я не могу гарантировать, что они будут запрашиваться в порядке специализации, не сталкиваясь с такими же проблемами связывания.

Существуют ли какие-либо шаблоны или методы для обработки ситуаций, таких какэто? (мое лучшее предположение могло бы помешать развертыванию; я буду держать его в своем заднем кармане, чтобы все не сказали «да, это единственный способ сделать это!»)

Ответы [ 5 ]

2 голосов
/ 11 октября 2010

Если у вас есть способ количественно оценить, как наша реализация может справиться с конкретной ситуацией, вы можете использовать вариант цепочки ответственности.

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

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

1 голос
/ 27 октября 2010

Решение может быть гибрид цепочки ответственности и шаблон посетителя.Посетитель может абстрагироваться от некоторых общих поведенческих аспектов.

1 голос
/ 26 октября 2010

Если вы можете определить какую-то правильную функцию упорядочения для каждого случая, вы можете сделать так, чтобы каждый класс регистрировал себя вместе с фабрикой для конкретного типа и сортировал на основе этого:

class Base;
class CaseInfo;

class TypeFactory {
 public:
  virtual Base MakeOne();

  //... Anything needed to implement Compare
}

// each derived type must inject a instance into AllTypes
dequeue<TypeFactory> AllTypes;

bool Compare(const TypeFactory&, const TypeFactory&, const CaseInfo&);
Base Best(const CaseInfo&);

Единственная проблема, которую я могудумаю, что сравнение будет нетривиальным.Для любого CaseInfo, он должен однозначно выбрать лучшее соответствие.Хитрость заключается в выборе бита «Все остальное».

0 голосов
/ 27 октября 2010

Я не уверен, что цепь ответственности можно смоделировать следующим образом. Обработчики цепи ответственности могут делать только 2 вещи. Обработайте запрос или передайте его следующему обработчику. Он не знает, какой обработчик следующий или кто должен обрабатывать запрос, он только знает, что не может.

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

Мое предложение, создать специальные обработчики, которые обрабатывают только один тип окна. Сделайте 1 универсальный обработчик. Затем упорядочите обработчики так, чтобы общий обработчик был последним. Любые специализированные обработчики попытаются запустить его в первую очередь, если ни один из них не найден, универсальный обработчик обработает запрос.

Если вы действительно хотели сделать то, что предлагаете, вы можете сделать несколько проходов обработчикам. Пройдите 1, только очень специализированные окна будут пойманы. Пройдите 2 менее специализированных окна, попадаются. И т.д. и т.п., пока вы не устанете делать пассы. Тем не менее, для меня ... Я говорю, не пытайтесь делать много с одним обработчиком. Если каждый обработчик отвечает за 1 окно, то порядок не имеет значения, они всегда будут обрабатывать правильный тип окна. Любые неизвестные окна будут перехвачены универсальным обработчиком.

0 голосов
/ 11 октября 2010

Вам нужно создать одну конкретную реализацию из множества доступных на основе некоторых данных времени выполнения - это звучит как Абстрактный Фабричный шаблон .

...