我应该用一堆函数来编写这个序列,这些函数需要非常长的参数列表,例如:
int main(int *argc,void **argv){ interpolate(x,y,z,x_interp,y_interp,z_interp,potential,&newPotential); compute_flux(x,&flux) compute_energy(x,&eng) ... // 10 other high-level function calls with long parameter lists ... return 0; }
或者我应该创建一个像这样调用的“SolvePotential”类:
int main(int *argc,void **argv){ potential = SolvePotential(nx,ny,nz,nOrder); potential.solve(); return 0; }
我将在SolvePotential中定义使用成员变量而不是长参数列表的函数,例如:
SolverPotential::solve(){ SolvePotential::interpolate() SolverPotential::compute_flux() SolverPotential::compute_energy() // ... // 10 other high-level function calls with NO parameter lists (just use private member variables) }
在任何一种情况下,我都怀疑我会非常重复使用这些代码……实际上,我只是在重构以帮助提高代码清晰度.
也许这就像争论“它是’12’还是’打了十几个’?”,但你怎么看?
解决方法
这不是一个单一的责任,大概是15:
SolverPotential::solve(){ SolvePotential::interpolate() SolverPotential::compute_flux() SolverPotential::compute_energy() // ... // 10 other high-level function calls with NO parameter lists (just use private member variables) }
这也使得维持类不变量几乎是不可能的,不是吗?什么时候调用compute_flux有效?解决?插?什么阻止我以错误的顺序做这件事?如果我这样做,班级是否会处于有效状态?我会从中获得有效数据吗?
但是,为什么它是 – 或者?为什么不能创建多个类和函数?
// This struct could be replaced with something like typedef boost::tuple<double,double,double> coord3d struct coord3d { double x,z; }; coord3d interpolate(const coord3d& coord,const coord3d& interpolated,double potential); // Just return the potential,rather than using messy output parameters double compute_flux(const coord3d coord&flux); // Return the flux instead of output params double compute_energy(const coord3d& coord); // And return the energy directly as well
当然,这些功能不一定是功能.如果必要/方便的话,每个都可以成为一个类,或者可能更好的是一个函子,以保持必要的状态,并且可能允许你将它们作为参数有效地传递给其他函数.
如果最佳性能很重要,您可能必须小心直接返回较大的结构,而不是使用输出参数,但我肯定首先要查看它是否是一个问题,即使它是,你可能可以避免使用表达模板输出参数.
如果你有一个可以执行许多独立操作的概念对象,它可能暗示你需要一些OOP,它应该被建模为具有许多成员函数的类,每个当然都维护类无论如何,何时以及为何被召唤,都是不变的.
如果您需要编写许多函数,将它们粘合在一起以形成新的,更大的功能,函数编程和函子很可能就是您所需要的.期望可组合函数的一个常见原因(但绝对不是唯一的)是,如果您需要在许多不同的数据集上执行相同的操作(甚至可能是几种不同的类型,都实现相同的概念).使编译器完成繁重的操作允许它与std :: transform或std :: for_each一起使用.
您可能还希望使用currying来逐步组合函数(也许某些函数可以使用一组固定参数进行参数化,这些参数在调用之间不会有所不同).再次,创建一个使用这些固定参数初始化的仿函数,然后在operator()中提供变化的数据.
最后,如果您只需要对某些可变数据执行一系列操作,那么普通的旧程序编程可能最适合您的需求.
最后,使用泛型编程,模板化必要的类和函数,以允许它们一起工作,而不必跳过像指针间接或继承这样的箍.
不要太忙于OOP.使用您可以使用的工具.
我不确定你的问题的背景是否足够肯定,但在我看来,你真正需要的不是一个类,它只是一个功能层次结构.
您的用户代码调用solve(). solve()内部调用,例如(为了示例而构成),interpolate()和compute_energy(). compute_energy()在内部调用compute_flux(),依此类推.每个函数只进行几次调用以执行构成函数职责的逻辑步骤.所以你没有一个庞大的课程,有十几个不同的职责,或者一个巨大的单片功能,它按顺序完成所有事情.
在任何情况下,“非常长的参数列表”都没有错(你通常可以通过将它们中的一些组合在一起来缩短它们,但即使你不能,也没有关于传递大量参数的“un-OOP”相反,它意味着函数很好地封装了其他所有东西.它所需要的只是在参数中传递,因此它并没有真正与应用程序的其余部分相关联.