【发布时间】:2013-08-20 09:07:49
【问题描述】:
我正在编写一个本质上需要非常灵活的代码,也就是说,以后也很容易被其他人扩展。但我现在面临一个问题,我什至不知道原则上如何正确处理:
我有一个相当复杂的Algorithm,它在某些时候应该会收敛。但由于其复杂性,有几个不同的标准来检查收敛,并且根据情况(或输入),我希望激活不同的收敛标准。此外,无需触及算法本身,就可以轻松创建新的收敛标准。所以理想情况下,我想要一个抽象的ConvergenceChecker 类,我可以从中继承并让算法有一个向量,例如像这样:
//Algorithm.h (with include guards of course)
class Algorithm {
//...
vector<ConvergenceChecker*> _convChecker;
}
//Algorithm.cpp
void runAlgorithm() {
bool converged=false;
while(true){
//Algorithm performs a cycle
for (unsigned i=0; i<_convChecker.size(); i++) {
// Check for convergence with each criterion
converged=_convChecker[i]->isConverged();
// If this criterion is not satisfied, forget about the following ones
if (!converged) { break; }
}
// If all are converged, break out of the while loop
if (converged) { break; }
}
}
问题在于每个ConvergenceChecker 都需要了解当前正在运行的Algorithm,但每个人可能需要从算法中了解完全不同的东西。说Algorithm 在每个周期中会更改_foo _bar 和_fooBar,但一个可能的ConvergenceChecker 只需要知道_foo,另一个可能是_foo 和_bar,并且可能是一些一天 ConvergenceChecker 需要 _fooBar 将被实施。以下是我已经尝试解决的一些方法:
- 为函数
isConverged()提供一个大参数列表(包含_foo、_bar和_fooBar)。缺点:大多数用作参数的变量在大多数情况下都不会使用,如果Algorithm将被另一个变量扩展(或类似的算法继承自它并添加一些变量),则必须修改相当多的代码. -> 可能,但丑陋 - 将
Algorithm本身(或指向它的指针)作为参数提供给函数isConverged()。问题:循环依赖。 - 将
isConverged()声明为好友函数。问题(除其他外):不能定义为不同ConvergenceCheckers 的成员函数。 - 使用函数指针数组。根本没有解决问题,还有:在哪里定义它们?
- (刚刚在写这个问题时想出了这个)使用一个不同的类来保存数据,比如
AlgorithmData有Algorithm作为朋友类,然后提供AlgorithmData作为函数参数。所以,就像 2. 但也许可以解决循环依赖问题。 (尚未对此进行测试。)
我很高兴听到您对此的解决方案(以及您在 5. 中看到的问题)。
补充说明:
- 问题标题:我知道“强依赖类”已经表明很可能有人在设计代码时做错了什么,但我想很多人最终可能会遇到这个问题并希望听到有可能避免它,所以我宁愿保持那种丑陋的表情。
- 太简单了?:实际上我在这里提出的问题并不完整。代码中会有很多不同的
Algorithms 相互继承,ConvergenceCheckers 当然应该在适当的情况下理想地工作,即使出现新的Algorithms 也不需要任何进一步的修改。也欢迎对此发表评论。 - 问题风格:希望问题既不太抽象也不太特殊,希望不要太长,通俗易懂。所以也请不要犹豫,对我提出这个问题的方式发表评论,以便我可以改进。
【问题讨论】:
-
也许您可以将装饰器模式用于收敛标准。然后,您可以根据需要添加任意数量的不同性质的不同标准,而不会引发争吵。
标签: c++ algorithm convergence