环境:
必须生成伪随机模式。有几种方法/或算法可用于创建不同的内容。所有算法都会生成一个字符列表(但可能是其他任何东西)......重要的是,它们都返回相同类型的值,并且需要相同类型的输入参数。
必须可以调用GetRandomPattern()方法,该方法每次调用时都会使用随机算法。
我的第一个方法是将每个算法放在它自己的函数中,并在每次调用GetRandompattern()时选择一个随机函数。但是我没有提出另一种选择它们的方式,而不是一个不切实际,丑陋且不灵活的转换案例陈述。
class PatternGenerator{
public:
list<char> GetRandomPattern();
private:
list<char>GeneratePatternA(foo bar);
list<char>GeneratePatternB(foo bar);
........
list<char>GeneratePatternX(foo bar);
}
每次调用 GetRandomPattern()方法时,选择随机GeneratePattern函数的好方法是什么?
或者整个班级的设计应该不同吗?
非常感谢
答案 0 :(得分:9)
为每个算法创建一个单独的类,每个类都对一个生成器类进行子类化。将这些对象的实例放入列表中。随机选择一个并使用它!
更一般地说,如果你开始使用相同的签名创建几个替代方法,那么尖叫的东西“将我们带入兄弟课程”:)
<强>更新强> 在指针建议出现之后,无法抗拒为面向对象的解决方案争论更多
答案 1 :(得分:5)
您可以创建一个函数指针数组。这避免了必须创建一大堆不同的类,尽管您仍然必须将函数指针分配给数组的元素。无论你怎么做,都会有很多重复的线条。在您的示例中,它位于GetRandomPattern方法中。在我的,它在PatternGenerator构造函数中。
#define FUNCTION_COUNT 24
typedef list<char>(*generatorFunc)(foo);
class PatternGenerator{
public:
PatternGenerator() {
functions[0] = &GeneratePatternA;
functions[1] = &GeneratePatternB;
...
functions[24] = &GeneratePatternX;
}
list<char> GetRandomPattern() {
foo bar = value;
int funcToUse = rand()%FUNCTION_COUNT;
functions[funcToUse](bar);
}
private:
generatorFunc functions[FUNCTION_COUNT];
}
答案 2 :(得分:1)
避免类似开关编码的一种方法是使用策略设计模式。例如:
class IRandomPatternGenerator
{
public:
virtual list<int> makePattern(foo bar);
};
class ARandomPatternGenerator : public IRandomPatternGenerator
{
public:
virtual list<int> makePattern(foo bar)
{
...
}
};
class BRandomPatternGenerator : public IRandomPatternGenerator
{
public:
virtual list<int> makePattern(foo bar)
{
...
}
};
然后,您可以根据RandomPatternGenerator实例的运行时类型选择特定算法。 (例如创建列表,如nicolas78建议)
答案 3 :(得分:1)
感谢您的所有好评。 我决定使用函数指针,主要是因为我以前不知道它们,它们似乎非常强大,它是一个了解它们的好机会,但也因为它节省了很多代码行。
如果我要使用Ruby / Java / C#,我已经决定建议的策略设计模式; - )
class PatternGenerator{
typedef list<char>(PatternGenerator::*createPatternFunctionPtr);
public:
PatternGenerator(){
Initialize();
}
GetRandomPattern(){
int randomMethod = (rand()%functionPointerVector.size());
createPatternFunctionPtr randomFunction = functionPointerVector.at( randomMethod );
list<char> pattern = (this->*randomFunction)();
return pattern;
}
private:
void Initialize(){
createPatternFunctionPtr methodA = &PatternGenerator::GeneratePatternA;
createPatternFunctionPtr methodB = &PatternGenerator::GeneratePatternB;
...
functionPointerVector.push_back( methodA );
functionPointerVector.push_back( methodB );
}
list<char>GeneratePatternA(){
...}
list<char>GeneratePatternB(){
...}
vector< createPattern > functionPointerVector;
可读性并没有像设计模式解决方案那样糟糕,添加新算法很容易,指针算术被封装在一个类中,它可以防止内存泄漏,而且非常快速有效...... / p>