摘要
将纯函数拆分为被动对象的优缺点是什么,这些对象描述了可以执行这些算法的算法和活动对象?请注意,由于函数没有副作用,情况会大大简化。
详细
我正在编写的代码部分(在Python 3中)将主要遵循函数式编程。
有一些(不可变的)数据。有一些算法。我需要将这些算法应用于数据,并获得结果。
算法可以表示为常规函数,它将使用标准操作进行转换(例如,我可以组合两个函数,然后使用functools.partial
冻结一些参数,然后将结果函数作为参数传递给另一个函数)。由于性能原因,许多较低级别的功能都会被记忆。
但是我想到了一个想法,也许我应该将算法表示为被动对象。这些对象本身无法执行任何操作。当我准备好执行时,我会将算法对象及其所需的所有输入提供给一个特殊的“计算”对象。这会比我的算法心智模型更好,但我担心我可能会错过这种方法的一些问题。
算法对象可以通过多种方式实现;也许甚至可以允许多个实现。假设我的算法是抽象类算法的实例;那么它的子类可以代表:
我之前从未这样做过,所以我希望得到一些关于这个想法的反馈。它是否提供任何真正的设计优势,除了我的主观感觉,它更“自然”?它会导致任何问题吗?
答案 0 :(得分:1)
我认为设计没有任何重大优势或劣势。
假设任何计算对象都可以运行任何算法,那么你的类Algorithm
可能会有一个名为execute
的函数,它知道如何运行算法。命名函数__call__
,现在您的Algorithm
类与Python可调用对象(包括函数)完全相同。
对于您的DSL代码字符串:根据您的设计,您将它们表示为Algorithm
的子类,它会覆盖execute
以运行解释程序。在其他设计下,您只需执行以下操作:
def createDSLAlgorithm(code):
def coderunner(*args, **kwargs):
DSLInterpreter().interpret(code, *args, **kwargs)
return coderunner
类似于创建一个函数,当被调用时将执行指定的表达式树。
当然,我可能会遗漏您计划在算法设计中添加的功能无法实现的功能。例如,不是所有 Python函数都具有可变属性。但是,由于用户定义的函数可以是闭包,可以具有属性,并且任何对象都可以表现得像一个函数"仅仅通过实施__call__
,我怀疑同一事物的名称不同。
如果它有助于代码可读性,那么选择自己的名称当然是一个小优势。将属性附加到"对象"可能会感觉更自然一点。如果你的计算对象要询问算法的某些已知属性,以帮助决定在计算它们时做什么(例如是否记忆),那么将它们附加到"函数"