2

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

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

While типов А и В как можно справиться с этим, B был разработан специально для этой ситуации и является правильным выбором.

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

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

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

ответ

0

Вам нужно создать одну конкретную реализацию из множества доступных на основе по некоторым данным во время выполнения - это звучит как Abstract Factory pattern.

+0

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

+0

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

+0

Хотел бы я сварить его до номера! Не вдаваясь в подробности, я пытаюсь взаимодействовать с разными окнами. Я должен обрабатывать, скажем, окна IE иначе, чем, например, окна апплетов Java. И если они не применяются, тогда как простое старое окно Win32. Чем больше я знаю о окне (который является сложным процессом, зависящим от типа окна), тем лучше я могу его обработать. Он может в конечном итоге распространиться на приложение, которому принадлежит окно. Я не могу стоять вне процесса и выбирать лучшего обработчика, если я не знаю, какой тип окна, и это знание связано с обработчиком. – Will

2

Если у вас есть способ количественно определить, как мы можем реализовать конкретную ситуацию, вы можете использовать вариацию «Цепь ответственности».

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

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

1

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

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&); 

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

0

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

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

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

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

1

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

+0

Хммм, интересно. Хотелось бы вам подробно рассказать об этом, это может быть лучший ответ. – Will

+0

Извинения! Я буду более конкретным. Я думаю, что посетитель может инкапсулировать логику решения наилучшей реализации. Отдельные узлы могут распространять вистор. Подумайте об этом как о кластере узлов, каждый из которых имеет свою собственную реализацию. Узел знает, что нужно сделать. Вистор посещает каждый узел и присоединяется, если он может оценить лучшую реализацию с определенной информацией, предоставляемой узлом. Если оценка не подходит, узел толкает вистор на следующий узел в цепочке. – zerodin