C ++: множественные политики, вызывающие друг друга - PullRequest
0 голосов
/ 30 ноября 2011

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

struct PolicyA {
  void foo() {
    // ...
  }
};

struct PolicyB {
  void bar() {
    // Need to call foo() here
  }
};

template <class A, class B> MyClass : A, B {};

У меня есть два варианта:

  • Передайте MyClass<A, B> в PolicyA и PolicyB в качестве параметров шаблона и сделайте что-то вроде dynamic_cast<MyClass<A, B>*>(this)->foo();.Однако это может легко стать очень сложным (особенно если это не только B вызов A, но также и другой способ).
  • Для каждой политики есть базовый класс, в котором все функции объявлены как чисто виртуальные.Это терпит неудачу, когда одна из функций нуждается в ее собственных параметрах шаблона, поскольку функции виртуального шаблона невозможны.

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

Редактировать: Смотрите также продолжение здесь .

1 Ответ

1 голос
/ 30 ноября 2011

Почему PolicyB не инкапсулирует PolicyA и не вызывает его так, как нужно?PolicyB, очевидно, знает о PolicyA - нет необходимости в базовых классах или наследовании.

Кажется, что во всех ваших Policy реализациях есть какой-то общий apply метод, с которым могут согласиться внешние вызывающие стороны?

Редактировать:

Правильно, поэтому, если это не просто случай, когда одна конкретная реализация Политики нуждается в доступе к другой, вам, вероятно, следует сосредоточиться на создании единого интерфейса для Policy - возможно, даже класс Rule, который можно объединить для формирования определенного Policy - см. Шаблон спецификации.

class Rule {
    allows(Foo foo);
}

class Policy {
    Rule rule = new NotNullRule().and(someOtherRule);

    void applyTo(Foo foo) {
        if (rule.allows(foo)) {
            return foo;
        }
        foo.disable();
    }
}

Называйте их как хотите, Condition, Rule, Specification - они полезны для сборки кусков логики таким образом, который не зависит от них.Затем, когда кто-то смотрит на PolicyA, он может ясно видеть правила / условия, которые управляют его поведением.

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

...