gpt4 book ai didi

function - DDD : The conondrum of Side-Effect-Free functions

转载 作者:行者123 更新时间:2023-12-04 15:24:26 25 4
gpt4 key购买 nike

对于这么多问题,我深表歉意,但我觉得只有将它们视为一个整体时才最有意义

注意 - 所有报价均来自 DDD: Tackling Complexity in the Heart of Software (第 250 和 251 页)

1)

Operations can be broadly divided into two categories, commands and queries.

...

Operations that return results without producing side effects are called functions. A function can be called multiple times and return the same value each time.

...

Obviously, you can't avoid commands in most software systems, but the problem can be mitigated in two ways. First, you can keep the commands and queries strictly segregated in different operations. Ensure that the methods that cause changes do not return domain data and are kept as simple as possible. Perform all queries and calculations in methods that cause no observable side effects



a) 作者暗示查询是一个函数,因为它不会产生副作用。他还指出函数将始终返回相同的值,我认为他的意思是对于相同的输入,我们将始终获得相同的输出?

b) 假设我们有一个方法 QandC(int entityId)它查询特定的域实体,从中提取某些值,这些值又用于初始化一个新的值对象,然后将该 VO 返回给调用者。不是根据上面的报价 QandC一个函数,因为它不会改变任何状态?

c) 但作者也认为对于相同的输入,函数总是会产生相同的输出,而 QandC 并非如此。 ,因为如果我们多次拨打 QandC ,它会产生不同的结果,假设在两次调用之间的时间这个实体被修改甚至删除。因此,我们如何声明 QandC是函数吗?

d)

Ensure that the methods that cause changes do not return domain data ...



原因是返回的非 VO 的状态可能会在 future 的某些操作中更改,因此此类方法的副作用是不可预测的?

e)

Ensure that the methods that cause changes do not return domain data ...



返回实体的查询方法是否仍被视为函数,即使它没有改变任何状态?

2)

VALUE OBJECTS are immutable, which implies that, apart from initializers called only during creation, all their operations are functions.

...

An operation that mixes logic or calculations with state change should be refactored into two separate operations. But by definition, this segregation of side effects into simple command methods only applies to ENTITIES. After completing the refactoring to separate modification from querying, consider a second refactoring to move the responsibility for the complex calculations into a VALUE OBJECT. The side effect often can be completely eliminated by deriving a VALUE OBJECT instead of changing existing state, or by moving the entire responsibility into a VALUE OBJECT.



一种)

VALUE OBJECTS are immutable, which implies that, apart from initializers called only during creation, all their operations are functions ... But by definition, this segregation of side effects into simple command methods only applies to ENTITIES.



我认为作者说在 VO 上定义的所有方法都是函数,这是没有意义的,因为即使在 VO 上定义的方法不能改变自己的状态,它仍然可以改变其他非 VO 对象的状态?!

b) 假设定义在实体上的方法不会改变任何状态,我们是否认为这样的方法是一个函数,即使它是在实体上定义的?

C)

... consider a second refactoring to move the responsibility for the complex calculations into a VALUE OBJECT.



为什么作者建议我们只从实体中重构那些执行复杂计算的功能?为什么我们不应该重构更简单的函数?

d)

... consider a second refactoring to move the responsibility for the complex calculations into a VALUE OBJECT.



无论如何,为什么作者建议我们应该从实体中重构函数并将它们放在 VO 中?仅仅因为它让客户更清楚这个操作可能是一个函数吗?

e)

The side effect often can be completely eliminated by deriving a VALUE OBJECT instead of changing existing state, or by moving the entire responsibility into a VALUE OBJECT.



这没有意义,因为作者似乎在争论如果我们将命令(即改变状态的操作)移动到 VO 中,那么我们本质上将消除任何副作用,即使命令正在改变状态。那么任何想法,作者实际上想说什么?

更新:

1b)

It depends on the perspective. A database query does not change state and thus has no side effects, however it isn't deterministic by nature, since as you point out the data can change. In the book, the author is referring to functions associated with value object and entities, which don't themselves make external calls. Therefore, the rules don't apply to QandC.



所以作者只描述了不进行外部调用的函数,因此 QandC不是作者描述的一种功能吗?

1c)

QandC does not itself change state - there are no side effects. The underlying state may be changed out of band however. Due to this, it is not a pure function.



但它也不是作者定义的无副作用功能吗?

1d)

Again, this is based on CQS.



我知道我在重复自己,但我认为书中的讨论是基于 CQS 而 CQS 不考虑 QandC由于 QandC 返回实体的机会,作为无副作用函数在将来的某个时候(通过其他操作)修改其状态?

1e)

It is considered a query from the CQRS perspective, but it cannot be called a function in the sense that a pure function on a VO is a function due to lack of determinism.


  • 我不太明白你想说什么(令人困惑的部分是粗体)。也许那同时 QandC被认为是一个查询,由于返回一个实体而不被认为是一个函数,这样的副作用是不可预测的,这使得 QandC本质上是不确定的
  • 所以作者只是在隐含假设 VO 中定义的任何操作都不会尝试更改非 VO 对象的状态的情况下做出这些陈述(参见 1e 中的引用)?

  • 2d)

    Given that VOs are immutable, they are a fitting place to house pure functions. This is another step towards freeing domain knowledge from technical constraints.


  • 我不明白为什么将功能从实体转移到 VO 会帮助将领域知识从技术约束中解放出来(我也不太确定你所说的技术是什么意思——技术与技术相关或......)?
  • 我认为将函数放入 VO 的其他原因是因为(对客户而言)这是一个函数更明显?

  • 2e)

    I view this as a hint towards event-sourcing. Instead of changing existing state, you add a new event which represents the change. There is still a net side effect, however existing state remains stable.



    我必须承认我对偶数源编程一无所知,因为我想首先围绕 DDD 进行思考。无论如何,所以作者并没有暗示仅仅将命令移动到 VO 会自动消除副作用,而是必须采取一些额外的行动(例如实现事件溯源),只是他“忘记”提到那部分?

    第二次更新:

    2d)

    One of the defining characteristics of an entity is its identity .... By placing business logic into VOs you can consider it outside of the context of an entity's identity. This makes it easier to test this logic, among other things.



    我有点明白你的意思(从远处考虑这个概念时),但另一方面我真的不明白。为什么实体内的函数会受到该实体身份的影响(假设该函数是纯函数,换句话说,它不会改变状态并且是确定性的)?

    2e)

    Yes that is my understanding of it - there is still a net "side effect". However, there are different ways to attain a side effect. One way is to mutate existing state. Another way is to make the state change explicit with an object representing that change.



    我 - 只是为了确定......从你的回答中我认为作者并没有暗示只需将命令移动到 VO 就可以消除副作用?

    II - 好的,如果我理解正确的话,我们可以将命令移动到 VO 中(即使 VO 不应改变任何状态,因此不应引起任何副作用)并且 VO 中的此命令仍然允许产生某种副作用,但是通过使状态更改显式(我将其解释为更改的内容作为 VO 返回给调用者),这种副作用在某种程度上更容易接受(或更可控)?

    3)我必须说我仍然不太明白为什么状态改变方法SC不应该返回域对象。也许是因为在 future 的某些操作中可能会更改非 VO,因此 SC 的副作用非常难以预测?

    第三次更新:

    Delegating the management of state to the entity and the implementation of behavior to VOs creates certain advantages. One is basic partitioning of responsibilities.



    a) 你是说,即使一个方法描述了一个实体的行为(因此包含这个方法的实体遵守 SRP )并且因此属于该实体,将它移到 VO 中仍然是一个好主意?因此,本质上,我们将一个实体的责任划分为两个更小的责任?

    b) 但是将行为转移到 VO 中不会基本上把这个实体变成一个纯粹的数据容器(我知道实体仍然会管理它的状态,但仍然......)?

    谢谢你

    最佳答案

    1a) 是的。关于将查询与命令分离的论述基于 Command-query separation principle .

    1b) 这取决于观点。数据库查询不会改变状态,因此没有副作用,但它本质上不是确定性的,因为正如您所指出的,数据可能会发生变化。在本书中,作者指的是与值对象和实体相关的函数,它们本身不进行外部调用。因此,该规则不适用于 QandC .然而,决定论可以被捏造,提供一定程度的“纯粹”。例如,可以创建一个可序列化的事务,以确保数据在其持续时间内不会更改。

    1c) QandC本身不会改变状态 - 没有副作用。然而,底层状态可以在带外改变。因此,它不是 pure function .但是,QandC 的限制不改变状态仍然是有值(value)的。 CQRS恰如其分地证明了该值这就是CQS在分布式场景中的应用。

    1d) 同样,这是基于 CQS。对此的另一个看法是 Tell-Don't-Ask principle .然而,鉴于对这些原则的理解,IMO 可以改变规则。例如,一个副作用方法可以返回一个代表结果的 VO。但是,在某些情况下,例如 CQRS + 事件溯源,命令返回 void 可能是可取的。

    1e) 从 CQRS 的角度来看,它被认为是一个查询,但在 VO 上的纯函数由于缺乏确定性而成为函数的意义上,它不能被称为函数。

    2a) 不,VO 函数不应该改变任何东西的状态,它应该返回一个新对象。

    2b) 是的。

    2c) 因为功能纯度在更复杂的场景中往往变得更加重要。但是,正如您所指出的,这并不是一个明确而明确的规则。它不应该像基于手头的领域那样基于复杂性。

    2d) 鉴于 VO 是不可变的,它们是存放纯函数的合适场所。这是将领域知识从技术限制中解放出来的又一步。

    2e) 我认为这是对事件溯源的暗示。您不是更改现有状态,而是添加一个代表更改的新事件。仍然存在净副作用,但现有状态保持稳定。

    更新

    1b) 是的。

    1c) 它是一个无副作用的函数,但它不是一个确定性函数,因为在给定相同输入的情况下,不能认为它总是返回相同的值。例如,返回当前时间的函数是一个无副作用的函数,但在后续调用中肯定不会返回相同的值。

    1d) QandC可以认为没有副作用,但不纯粹。查看函数纯度的另一种方法是引用透明性——在不改变程序行为的情况下用函数值替换函数调用的能力。换句话说,提出问题并不会改变答案。 QandC可以保证这一点,但仅限于诸如事务之类的上下文中。所以 QandC 可以被认为是一个函数,但只能在特定的上下文中使用。

    1e) 我认为令人困惑的部分是作者专门讨论了 VO 和实体上的功能 - 而不是数据库查询,我们正在讨论两者。我的陈述将讨论扩展到数据库查询和 CQRS 给定某些限制,即环境事务。

    2d) 我可以看出我说的话有点含糊,我越来越懒了。实体的定义特征之一是其身份。它在其整个生命周期中保持其身份,而其状态可能会发生变化。通过将业务逻辑置于 VO 中,您可以在实体身份的上下文之外考虑它。这使得测试这个逻辑变得更容易,等等。

    2e)是的,这是我的理解 - 仍然存在净“副作用”。但是,有不同的方法可以达到副作用。一种方法是改变现有状态。另一种方法是使用代表该更改的对象使状态更改显式。

    更新 2

    2d) 这个特定的观点可以争论或可以是一个偏好问题。一种观点是该想法基于单一职责原则 (SRP)。实体的职责是将身份与行为和状态关联起来。行为将输入与现有状态相结合以产生状态转换。将状态的管理委托(delegate)给实体,将行为的实现委托(delegate)给 VO 会产生一定的优势。一是基本职责划分。另一个更微妙,也许更具争议性。逻辑可以以无状态的方式考虑。这使得思考这种逻辑更容易,更像是思考一个数学方程式,其中所有变化都是显式的 - 没有隐藏状态。

    2e.1) 是的,消除净副作用会改变行为,这不是目标。

    2e.2) 是的。

    3) 返回 void 的命令有几个优点。一是他们自然而然地更擅长异步场景——无需等待结果。另一个是它允许您将操作表示为单个命令对象 - 同样,因为没有返回值。这适用于 CQRS 和事件溯源。在这些情况下,任何命令输出都作为事件而不是结果进行调度。但同样,如果这些要求不适用,则返回结果对象可能是合适的。

    更新 3

    a) 是的,这是一种特定类型的分区。

    b) 实体的职责是通过委派给 VO 并应用由此产生的状态更改来协调行为。

    关于function - DDD : The conondrum of Side-Effect-Free functions,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14510273/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com