Выбор правильной стратегии на основе двух типов объектов

Я не знаю, как назвать эту проблему, поэтому я постараюсь объяснить как можно лучше.

Я хочу иметь возможность переключать стратегии в зависимости от типов двух разных объектов. Чтобы сделать это, я думаю пометить объекты с типом enum и иметь «реестр» (массив) этих стратегий. В идеале, к правильной стратегии можно обратиться с помощью некоторой простой операции, например, побитового оператора между двумя типами.

Этот псевдокод может облегчить понимание того, что я пытаюсь объяснить:

enum Type { A, B, C }

struct Object {
Type type;
}

class ActionRunner {
vector<Strategy> strategies;

void registerStrategy(type1, type2, strategy) {
strategies[type1 operator type2] = strategy;
}

void runStrategyFor(type1, type2) {
strategies[type1 operator type2].execute();
}
}

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

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

У кого-нибудь есть какие-нибудь подсказки / советы о том, что я могу использовать для этого?

PS: я знаю, что преждевременная оптимизация — это плохо, но я просто пытаюсь выяснить, можно ли решить эту проблему простым способом.

——- РЕДАКТИРОВАТЬ ————————————————

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

Я хотел бы иметь структуру класса, в которой есть объекты определенного типа «BaseClass» и объект «процессор», который принимает два объекта, производных от «BaseClass», и выполняет правильную стратегию для них. Что-то вроде этого:

class Processor {
void run (DerivedA a, DerivedB b);
}

class BaseClass {}
class DerivedA: public BaseClass {}
class DerivedB: public BaseClass {}

BaseClass a = new DerivedA;
BaseClass b = new DerivedB;

processor.run(a, b)

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

Я имею в виду что-то вроде двойной отправки в сочетании с подчиненным (процессором) объектом, который, я думаю, будет работать, но это кажется ужасно сложным и, вероятно, болью в обслуживании и расширении.

Спасибо!

0

Решение

Во втором предложении вашего вопроса мне позвонили:

Я хочу иметь возможность переключать стратегии в зависимости от типов двух разных объектов.

Похоже, вы хотите выполнить двойная отправка. Смотрите вопрос (в частности, ответы на вопрос ;-)) на Двойная рассылка / мультиметоды в C ++ о том, как реализовать это в C ++.

0

Другие решения

Это классический пример использования map вместо массива. Массив на самом деле является частным случаем map с ключом, определенным как целое число. В вашем случае ключ является кортежем, поэтому простой массив не подойдет, и вы столкнетесь с коллизиями (даже если вам повезет с вашим конкретным вводом, ваш код будет крайне ненадежным).

Вы можете иметь промежуточное решение, между простым array а также map: 2D arrayс вашими 2 типами, служащими индексами для строк и столбцов.

0

По вопросам рекламы [email protected]