DDD:Side-Effect-Free功能的概念
我为这么多问题道歉,但我觉得他们只有在被视为一个单位时才最有意义
注 – 所有报价均为DDD: Tackling Complexity in the Heart of Software(第250和251页) 1)
a)作者暗示查询是一个函数,因为它不会产生副作用.他还指出函数将始终返回相同的值,我认为他的意思是,对于相同的输入,我们将始终获得相同的输出? b)假设我们有一个方法QandC(int entityId),它查询特定的域实体,从中提取某些值,这些值又用于初始化一个新的Value Object,然后将这个VO返回给调用者.是不是根据上面的引用QandC一个函数,因为它不会改变任何状态? c)但是作者还争辩说,一个函数总是产生相同的输出,这与QandC不同,因为如果我们对QandC进行多次调用,它将产生不同的结果,假设在两者之间的时间调用此实体已被修改甚至删除.因此,我们如何宣称QandC是一个功能? d)
原因是在未来的某些操作中可能会改变返回的非VO的状态,因此这些方法的副作用是不可预测的? E)
是一个返回仍被视为函数的实体的查询方法,即使它没有更改任何状态? 2)
一个)
我认为作者说VO上定义的所有方法都是函数,这没有意义,因为即使在VO上定义的方法不能改变它自己的状态,它仍然可以改变其他非VO对象的状态. ?! b)假设在实体上定义的方法不会改变任何状态,我们是否认为这样的方法是一个函数,即使它是在一个实体上定义的? C)
为什么作者建议我们只应该从那些执行复杂计算的函数中重构?为什么我们不应该重构更简单的函数? d)
无论如何,为什么作者建议我们应该从实体中重构函数并将它们放在VO中?只是因为它使客户端更明显地认为这个操作可能是一个函数? E)
这没有意义,因为如果我们将一个命令(即改变状态的操作)移动到一个VO中,那么作者就是在争论,那么即使命令正在改变状态,我们实质上也会消除任何副作用.所以任何想法,作者究竟试图说什么? 更新: 图1b)
所以作者只描述了不进行外部调用的函数,因此QandC不是作者描述的一种函数? 1C)
但它也不是意义作者定义的Side-Effect-Free功能吗? 1D)
我知道我在重复自己,但我认为书中的讨论是基于CQS而CQS并不认为QandC是副作用免费功能,因为QandC返回的实体有可能修改其状态(通过其他操作)将来某个时候? 1E)
>我不太明白你想说什么(令人困惑的部分是粗体).也许虽然QandC被认为是一个查询,但由于返回一个实体而不被视为一个函数,这样的副作用是不可预测的,这使得QandC本质上是一个非确定性的 2D)
>我不明白为什么将功能从实体转移到VO会有助于将领域知识从技术限制中解放出来(我也不确定你所说的技术 – 技术与技术相关还是……)? 2E)
我必须承认我对偶数源编程一无所知,因为我想首先围绕DDD.无论如何,作者并没有暗示只是将命令移动到VO会自动消除副作用,而是必须采取一些额外的行动(例如实施事件采购),只是他“忘了”提到那部分? 第二次更新: 2D)
我不知道你正在做什么(当从远处思考这个概念时),但另一方面我真的没有.为什么实体中的函数会受到该实体的身份的影响(假设此函数是纯函数,换句话说它不会改变状态并且是确定性的)? 2E)
我 – 只是为了确定…从你的回答中我得知,作者并没有暗示仅仅通过将命令移入VO就可以消除副作用? II – 好的,如果我理解正确的话,我们可以将命令移动到VO中(即使VO不应该改变任何状态,因此不应该引起任何副作用)并且VO中的这个命令仍然允许产生某种副作用,但这种副作用在某种程度上更容易被接受(或者更可控)通过使状态变化显式化(我将其解释为更改后的东西作为VO返回给调用者)? 3)我必须说我仍然不太明白为什么状态改变方法SC不应该返回域对象.也许是因为在未来的某些操作中可能会改变非VO,因此SC的副作用非常难以预测? 第三次更新:
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并应用由此产生的状态变化来协调行为. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- C#调用Python模块的方法
- C# 多态性的深入理解
- Xml:MalformedByteSequenceException: Invalid byte 2 of 2
- sax错误:org.xml.sax.SAXParseException: Content is not
- logback logback.xml常用配置详解(二)<appender>
- oracle10g – Oracle在后面,Access在前面?
- 如何为iOS和macOS编译libffi?
- 展平/非规范化R聚合函数的结果
- 电商平台CRM规划:由Axure页面管理联想到的NoSQL的过滤器(
- ruby-on-rails – NameError:未初始化的常量Object :: Use
- 我如何解析tcl脚本中的xml文件并读取一些标记属性
- 【Cocos2d-x 3.x】 调度器Scheduler类源码分析
- 除非另外还指定了 TOP 或 FOR XML,否则,ORDER
- c# – 我可以在Visual Studio中为UnitTest / Loa
- c# – 如何暂时禁用Visual Studio自动生成的事件
- Cocos2d-x3.3Final(1) ListView常用成员函数(C
- SQLite学习笔记2
- c – 如何使openCV Backgroundsubtraction KNN算
- c# – MVC 5:如何在Global.asax中调用Applicati
- 解决swfupload items size=0