Decolator, Mix-Inのような継承関係
Decolatorパターンの場合、内部で持っているコンポーネントの振る舞いが分かりにくい。Mix-Inの場合、プロパティとなるClassがtemplate classとなってしまって、複雑になる。
そこで、状況によってはあ下記のような継承もありかな。
- RuleBaseはルール f : double -> doubleを複数保持する。
- RuleBase::apply(double x)は、登録された順にルールをxに適用する。
- RuleAは、ルールx + 1.0をRuleBaseに登録する。
- RuleBは、ルールx * 3.0をRuleBaseに登録する。
- Cは、RuleAとRuleBを持っている。継承の順番にRuleBaseに登録する。
class RuleBase { public: RuleBase() { } virtual ~RuleBase() {} void addRule(const std::function<double(double)>& f) { _f.push_back(f); } double apply(double x) const { for (auto& f : _f) { x = f(x); } return x; } private: std::list<std::function<double(double)> > _f; }; class RuleA : virtual RuleBase { public: RuleA() { addRule([&](double x) {return rule(x); }); } virtual ~RuleA() {} private: double rule(double x) const { return x + 1.0; } }; class RuleB : virtual RuleBase { public: RuleB() { addRule([&](double x) {return rule(x); }); } virtual ~RuleB() {} private: double rule(double x) const { return x * 3.0; } }; class C : RuleA, RuleB, virtual RuleBase { public: C() {} double get(double x) const { return RuleBase::apply(x); } }; int main() { C c; std::cout << c.get(0.5) << std::endl; // (0.5 + 1.0) * 3.0 return 0; }