根据数据的不同行为

时间:2011-05-24 19:48:28

标签: c++ design-patterns inheritance polymorphism

让我们把它作为一个简单的例子。假设我有一组Number个对象,然后可以甚至奇数

假设我想遍历此集合并处理每个元素。该过程取决于元素的类型:甚至奇数

示例:打印每个元素,例如:

  • 如果Number是偶数,我“这是偶数。”

  • 如果Number是奇数,我“这是一个奇数。”

但是,我稍后可能会决定仅偶数打印“偶数”。

因此,正如我们所见,通过使用虚函数,可以通过继承多态> 解决这个问题:

class Number {/*...*/};              // base class
class Even : public Number {/*...*/} // derived class
class Odd  : public Number {/*...*/} // derived class

但是,如何在以后执行不同行为的过程中提供灵活性,如上例所示?另外,还有另一种继承和多态的方法吗?因为我不想仅仅因为特定的计算/过程而创建继承树。

最初的问题是根据对象的类型执行不同的数学模型,并且数学模型对于给定类型的对象不是唯一的(因为我可以打印偶数的方式不是唯一的)。


编辑:很有趣的是,这篇文章因为很难说出被问到的内容而被关闭了。以下几个答案的作者似乎不同意这一点,因为所有人都能理解并回复我所寻找的内容。

3 个答案:

答案 0 :(得分:3)

好吧,您可以使用Strategy pattern:有两个类EvenStrategy和OddStrategy,将行为放入其中,然后在构建orm时将它们添加到集合中的Even和Odd类。

答案 1 :(得分:2)

您可以将Strategy层次结构与实际数字分开。这样就不需要人工类层次结构,并且您可以自由地更改数字(值)类型和操作之间的关联,甚至是运行时。可以定义关联

  • 如果您坚持使用Number类层次结构,那么在Number子类(Odd,Even)和策略类(OddNumberStrategy,EvenNumberStrategy)或
  • 之间
  • 通过具体值和策略实例之间的映射(当然,这仅适用于具有相对较少的具体值),或
  • 通过选择器功能。

作为替代方法,您可以将策略重新定义为处理程序,每个策略都可以决定给定值是否适合他们处理,如果是,则处理它们。这些处理程序甚至可以链接或存储在一个集合中(然后针对每个值进行迭代),这样一些值可以由多个“重叠”处理程序处理,如果这适合你的话。

答案 2 :(得分:2)

有几种方法可以解决这个问题,但一般来说它们都使用组合。让我们举个例子吧。假设我们有一个整数数组:

int foo[] = {0,1,2,3,4,5,6,7,8,9};

现在,我们要打印出所有奇数:

void printIfOdd(int number) {
    if(number % 2 == 1)
        std::cout << number << std::endl;
}

std::for_each(foo, foo+10, printIfOdd);

我们可以为偶数做同样的事情。如果你想要打印两者,你可以编写函数(在这种情况下不是函数组合的数学意义):

template<class T>
class apply_all_functor {
public:
    apply_all_functor(T f1, T f2) : f1(f1), f2(f2) {}

    void operator()(int number) {
        f1(number);
        f2(number);
    }
private:
    T f1, f2;
};

template<class T>
apply_all_functor<T> apply_all(T f1, T f2) {
    return apply_all_functor<T>(f1, f2);
}

std::for_each(foo, foo+10, apply_all(printIfOdd, printIfEven);

组合的想法当然也可以扩展到对象,这会产生像Strategy-PatterDecorator-Pattern这样的模式。您可以看到代码here的所有完整示例。