加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

DDD:Side-Effect-Free功能的概念

发布时间:2020-12-13 20:47:52 所属栏目:百科 来源:网络整理
导读:我为这么多问题道歉,但我觉得他们只有在被视为一个单位时才最有意义 注 – 所有报价均为DDD: Tackling Complexity in the Heart of Software(第250和251页) 1) Operations can be broadly divided into two categories,commands and queries. … Operations
我为这么多问题道歉,但我觉得他们只有在被视为一个单位时才最有意义

注 – 所有报价均为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),它查询特定的域实体,从中提取某些值,这些值又用于初始化一个新的Value Object,然后将这个VO返回给调用者.是不是根据上面的引用QandC一个函数,因为它不会改变任何状态?

c)但是作者还争辩说,一个函数总是产生相同的输出,这与QandC不同,因为如果我们对QandC进行多次调用,它将产生不同的结果,假设在两者之间的时间调用此实体已被修改甚至删除.因此,我们如何宣称QandC是一个功能?

d)

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

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

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,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.

但它也不是意义作者定义的Side-Effect-Free功能吗?

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本质上是一个非确定性的
>因此,作者只是在隐含的假设下制作这些陈述(见1e中的引用),即VO中定义的操作不会试图改变非VO对象的状态吗?

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不应该返回域对象.也许是因为在未来的某些操作中可能会改变非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不改变状态的限制仍然是有价值的.该值在CQRS中得到??了适当的证明,这是CQS在分布式场景中的应用.

1d)同样,这是基于CQS.对此的另一种看法是Tell-Don’t-Ask principle.然而,鉴于对这些原则的理解,该规则可以弯曲IMO.副作用方法可以返回表示例如结果的VO.但是,在诸如CQRS事件源之类的某些场景中,可能希望命令返回无效.

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

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

2b)是的.

2c)因为在更复杂的情况下,功能纯度往往变得更加重要.但是,正如您所指出的,这不是一个明确而明确的规则.它不应该基于复杂性,而应该基于手头的域.

2d)鉴于VO是不可变的,它们是容纳纯粹功能的合适场所.这是将领域知识从技术限制中解放出来的又一步骤.

2e)我认为这是对事件采购的暗示.您可以添加表示更改的新事件,而不是更改现有状态.仍存在净副作用,但现有状态仍然稳定.

UPDATE

1b)是的.

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

1d)QandC可以被认为是无副作用,但不是纯粹的.查看函数纯度的另一种方法是引用透明性 – 在不改变程序行为的情况下,通过其值替换函数调用的能力.换句话说,提问不会改变答案. QandC可以保证,但仅限于诸如交易的上下文中.所以QandC可以被认为是一个函数,但只能在特定的上下文中.

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

2d)我可以看到我说的有点模糊,我变得懒惰.实体的一个明确特征是其身份.它在整个生命周期中保持其身份,而其状态可能会发生变化.通过将业务逻辑放入VO,您可以将其视为在实体身份的上下文之外.这样可以更容易地测试这种逻辑.

2e)是的,这是我对它的理解 – 仍有净副作用.但是,有不同的方法可以获得副作用.一种方法是改变现有状态.另一种方法是使用表示该更改的对象使状态更改显式.

更新2

2d)这个特定点可以论证或可以是偏好问题.一个观点是该想法基于单一责任原则(SRP).实体的责任是身份与行为和国家的关联.行为将输入与现有状态组合以产生状态转换.将国家管理委派给实体并向VO实施行为会产生某些优势.一个是责任的基本划分.另一个更微妙,也许更有争议.逻辑可以以无状态的方式被考虑.这样可以更容易地思考这种逻辑,更像是思考所有变化都是明确的数学方程式 – 没有隐藏状态.

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

2e.2)是的.

3)返回void的命令有几个优点.一个是他们在异步场景中变得更加擅长 – 无需等待结果.另一个是它允许您将操作表示为单个命令对象 – 再次,因为没有返回值.这适用于CQRS和事件采购.在这些情况下,任何命令输出都将作为事件而不是结果分派.但同样,如果这些要求不适用,则返回结果对象可能是合适的.

更新3

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

b)实体的责任是通过委托VO并应用由此产生的状态变化来协调行为.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读