我正在编写一个本质上需要非常灵活的代码,即以后也很容易被其他人扩展。但我现在面临一个问题,我什至不知道原则上如何正确处理:
我有一个相当复杂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
将由另一个变量扩展(或类似的算法从它继承并添加一些变量),则必须修改相当多的代码。-> 可能,但丑陋 - 将函数本身(或指向它
isConverged()
的Algorithm
指针)作为参数。问题:循环依赖。 - 声明
isConverged()
为友元函数。问题(除其他外):不能定义为不同ConvergenceChecker
s 的成员函数。 - 使用函数指针数组。根本没有解决问题,还有:在哪里定义它们?
- (刚刚在写这个问题时想出了这个)使用一个不同的类来保存数据,比如
AlgorithmData
作为Algorithm
一个朋友类,然后提供AlgorithmData
作为函数参数。所以,就像 2. 但也许可以解决循环依赖问题。(尚未对此进行测试。)
我很高兴听到您对此的解决方案(以及您在 5. 中看到的问题)。
进一步说明:
- 问题标题:我知道“强依赖类”已经说过,很可能有人在设计代码时做错了什么,但我想很多人最终可能会遇到这个问题,并想听听可能性避免它,所以我宁愿保持那个丑陋的表情。
- 太简单了?:其实我这里提出的问题并不完整。代码中会有很多不同
Algorithm
的 s 相互继承,ConvergenceChecker
当然即使有新Algorithm
的 s 出现,s 也应该在适当的情况下理想地工作而无需任何进一步的修改。也欢迎对此发表评论。 - 问题风格:希望问题既不太抽象也不太特别,希望不要太长,通俗易懂。因此,请不要犹豫,对我提出这个问题的方式发表评论,以便我可以改进。