当我们将计算与副作用分开时,我们将“询问世界”的代码放在哪里?


10

根据命令查询分离原则,以及使用Clojure演示的“ 数据中的思考”和“ DDD”,应将副作用(修改世界)与计算和决策分开,以便更容易理解和测试这两个部分。

这就留下了一个悬而未决的问题:我们应该把“问世界”放在边界的哪个位置?一方面,从外部系统(例如数据库,扩展服务的API等)请求数据不是参照透明的,因此不应与纯计算和决策代码放在一起。另一方面,将它们从计算部分中分离出来并作为参数传递是有问题的,甚至是不可能的,因为因为我们可能事先不知道可能需要请求哪些数据。


1
这就是回调的概念。如果您事先不知道可能需要什么数据,请提供对计算代码的回调,在其中可以指定所需的数据,并让其他层进行实际的获取和提供。 。如果需要异步,则回调甚至可以指定另一个函数,以在获取的数据可用时调用该函数。
Marjan Venema

1
@MarjanVenema,这也是我想到的唯一选择。仅从理论上讲:如果该方法(否则没有副作用)调用了副作用回调,则它将变为副作用。我在这里的问题可能是我假设副作用的分离计算要求该计算是参照透明的。虽然这不是必须的。
Alexey

1
如果那是您的担心,那么您的计算就不够细致。您需要抽象出需要哪些其他数据/步骤的决策。因此,根据需要哪些数据的决策位置,将全部计算分为多个步骤。然后有某种“指挥官”来管理整个计算的工作流程:开始每一步,从每一步取回信息,用它来决定下一步和所需的数据,开始获取过程以获取信息,然后传递提取的数据进入计算的下一步。
Marjan Venema

Answers:


1

另一方面,将它们从计算部分中分离出来并将其作为参数传递是有问题的,甚至是不可能的,因为因为我们可能事先不知道可能需要请求哪些数据。

如注释中所述,这是一个实例,其中传递了检索数据的能力(例如,一等函数,实现接口的对象等),提供了隔离副作用的便捷机制。

主体纯净的高阶函数具有不确定的纯度:http : //books.google.com/books? id=Yb8azEfnDYgC&pg= PA143# v=onepage&q&f= false

我已经写过有关此问题的文章,称这类函数为潜在纯函数:http : //adamjonrichardson.com/2014/01/13/potentially-pure-functions/

如果您将潜在的纯函数与穿透函数(缺少分支结构,并且尽可能少地做)结合在一起(我称之为隔离集),则可以相当有效地隔离副作用并创建可测试的代码: http:// adamjonrichardson.com/2014/01/15/isolated-side-effects-using-isolation-sets/


0

您将结果存储在类中,乍一看似乎有些奇怪,但确实会导致代码更简单。例如,调用方中没有临时变量。

class database_querier
    feature -- queries
        was_previous_query_ok : boolean is
            do
                Result = …
            end

        previous_query_result : string is 
            requires
                was_previous_query_ok
            do
                Result = query_result
            end

    feature -- commands
        query_db (…) is
            do
                …
                query_result = bla
            end

    feature {none} --data
        query_result : string

1
喜欢在野外看到埃菲尔铁塔。
SBI 2014年

@sbi只是伪代码。:-)
ctrl-alt-delor 2014年

亲近得足以让我高兴;)
SBI
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.