静态方法的函数式编程建议如何影响可测试性
本文关键字:何影响 影响 可测试性 函数 编程 静态方法 | 更新日期: 2023-09-27 18:15:58
我越深入到函数式编程中,就越喜欢静态方法而不是非静态方法。你可以在这本书中读到这个建议,例如:
http://www.amazon.de/Functional-Programming-Techniques-Projects-Programmer/dp/0470744588
当然,如果你考虑功能纯度,这是有道理的。一个静态函数站在那里说:"我不需要任何状态!">
然而,这对可测试性有何影响?我的意思是,一个有很多静态方法的系统不是很难测试吗(因为静态方法很难模拟(?或者mock在函数式编程中起着次要作用吗?如果是,为什么?
编辑
既然有人怀疑这本书是否真的提出了这个建议。我会引用更多的话。我希望这对奥利弗·斯特姆来说没问题。
使用静态方法
静态方法是一个基本思想,值得考虑作为一个通用的指导方针。它得到了许多面向对象程序员的支持,从函数的角度来看,函数在大多数情况下都可以是静态的。任何纯函数都可以是静态的。(…(
有些人可能会争辩说,总是传递所有参数的想法意味着你没有尽可能多地利用面向对象的想法。事实上,这可能是真的,但也许是因为面向对象的概念没有像它们应该的那样考虑并行执行的问题。(…(
最后,推荐一条准则:当您编写了一个不需要访问其所在类中任何字段的方法时,请将其设置为静态!
顺便说一句,到目前为止已经有了很好的答案。谢谢你!
看待这一点的一种方法是,对于函数式编程,您只需要模拟特定函数所需的状态(通过提供合适的输入(。对于OO编程,您需要模拟类内部工作所需的所有状态。
功能程序还有一个附带的好处,那就是你可以保证用相同的输入重复相同的测试会得到相同的结果。在经典OO中,您不仅要保证相同的输入,还要保证相同的整体状态。
在架构良好的OO代码中,差异将是最小的(因为类将具有定义良好的职责(,但功能测试的需求仍然是等价OO测试的严格子集。
(我意识到函数式编程风格可以通过不可变的对象来使用OO——请阅读上面提到的OO是"具有多状态的面向对象编程"(
编辑:
正如Fredrik所指出的,函数方法的重要部分不是它们是静态的,而是它们不会改变程序的状态。"纯"函数是从一组输入到一组输出的映射(相同的输入总是给出相同的结果(,没有其他影响。
我认为静态方法本身不是问题,当它们开始对的静态数据进行操作时,问题就来了。只要静态方法将输入作为参数,对其进行操作并返回结果,我就认为测试它们没有问题。
即使我在代码中不追求函数方法,我也倾向于尽可能使方法保持静态。但我认为在引入静态状态或静态类型之前非常小心。
纯函数编程中的所有"状态"都来自输入。要对功能程序进行单元测试,您需要创建测试输入并观察输出。如果你的方法不能通过给它们测试输入和观察输出来进行测试,那么它们的功能就不够了。
在函数式编程中,您希望模拟函数而不是对象。因此,如果您想在不依赖中的某些ComplicatedAndLongFunction
的情况下测试函数f
f(x)
{
myx = g(x);
y = ComplicatedAndLongFunction(myx);
myy = h(y)
return myy;
}
您可能希望将f
与ComplicatedAndLongFunction
解耦,方法是将后者注入f:
f(x, calc)
{
myx = g(x);
y = calc(myx);
myy = h(y)
return myy;
}
因此您可以在测试中指定calc
的行为。
这就提出了一个问题(至少在我的脑海中(,即是否有模拟框架可以轻松地指定对函数的期望,而不必返回到对象。