让我们把它作为一个简单的例子。假设我有一组Number
个对象,然后可以甚至或奇数。
假设我想遍历此集合并处理每个元素。该过程取决于元素的类型:甚至或奇数。
示例:打印每个元素,例如:
如果Number
是偶数,我“这是偶数。”
如果Number
是奇数,我“这是一个奇数。”
但是,我稍后可能会决定仅偶数打印“偶数”。
因此,正如我们所见,通过使用虚函数,可以通过继承和多态> 解决这个问题:
class Number {/*...*/}; // base class
class Even : public Number {/*...*/} // derived class
class Odd : public Number {/*...*/} // derived class
但是,如何在以后执行不同行为的过程中提供灵活性,如上例所示?另外,还有另一种继承和多态的方法吗?因为我不想仅仅因为特定的计算/过程而创建继承树。
最初的问题是根据对象的类型执行不同的数学模型,并且数学模型对于给定类型的对象不是唯一的(因为我可以打印偶数的方式不是唯一的)。
编辑:很有趣的是,这篇文章因为很难说出被问到的内容而被关闭了。以下几个答案的作者似乎不同意这一点,因为所有人都能理解并回复我所寻找的内容。
答案 0 :(得分:3)
好吧,您可以使用Strategy pattern:有两个类EvenStrategy和OddStrategy,将行为放入其中,然后在构建orm时将它们添加到集合中的Even和Odd类。
答案 1 :(得分:2)
您可以将Strategy层次结构与实际数字分开。这样就不需要人工类层次结构,并且您可以自由地更改数字(值)类型和操作之间的关联,甚至是运行时。可以定义关联
作为替代方法,您可以将策略重新定义为处理程序,每个策略都可以决定给定值是否适合他们处理,如果是,则处理它们。这些处理程序甚至可以链接或存储在一个集合中(然后针对每个值进行迭代),这样一些值可以由多个“重叠”处理程序处理,如果这适合你的话。
答案 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-Patter和Decorator-Pattern这样的模式。您可以看到代码here的所有完整示例。