什么是DCI,它如何与Rails相适应?

24

最近和同事就在Rails应用程序中设计和编写模型的不同方法进行了一场辩论,这让我接触到了DCI在Rails上下文中

然而,即使在查看此示例应用程序之后,我仍然无法完全理解整个概念。

目前,我在编写Rails应用程序时倾向于更多地遵循“按照书本”的方式。

因此,我想问几个问题--

  • 什么是DCI,与普通的MVC(以及Rails中的vanilla ActiveRecord)相比,在实现MVC时有什么优势?
  • 如何在Rails中实现它(换句话说,所有这些模块是什么意思)?

编辑

我想在 RoR 的背景下进一步扩展我的问题 - 在 Rails 中,模型和控制器之间是否建议使用另一层抽象?在不同规模的应用程序中有多普遍?


你的问题非常宽泛,因此很难回答。有很多地方似乎你还没有完全理解DCI,这使得在DCI上下文中回答一些问题更加困难。如果你的目标是DCI相关的话,我可以帮助你,但你需要缩小范围。 - Rune FS
我主要想了解的是什么是DCI。至于Rails实现,一个简单的例子或者两行说明都可以。 - GeReV
好问题。在阅读这篇文章之前,我不知道我最近一直渴望的范式有一个名字。我一直在看我维护的代码(我没写过的),并思考“这需要数据和行为之间的类别分离”。我想这正是DCI试图做的。 - Tom W
不是特指 DCI,但在谷歌搜索“Rails Service Objects”将会让你体验到类似 DCI 概念的应用方式。同时自我推销一下:http://www.sitepoint.com/using-wisper-to-decompose-applications/。 - Kris
如果你仍在寻找与DCI相关的Ruby示例,请查看以下演示文稿,它受到了几个DCI问题的启发(其中之一就是这个):http://www.youtube.com/watch?v=ZUADinlqHwk - Rune FS
4个回答

21
DCI是一种范式,因此不仅仅是设计应用程序的一种方式。它是一种思考建模和代码结构的方式。 DCI的重要部分之一是保持系统是什么(领域模型)以及系统执行的操作(功能)是分开的。 DCI不是解决与MVC相同问题的不同方法,因此你的第一个问题实际上无法回答。您可以同时使用MVC和DCI,这不是巧合,因为Trygve Renskaug是MVC和DCI的创始人。他最近在谷歌组“对象组合”中回答了类似的问题
您链接的示例违反了一些基本思想,例如将角色保留为上下文私有属性,而且我实际上也找不到单个上下文,但这可能是由于浏览代码的时间太短。

我自己不知道RoR,所以不能给你一个RoR的例子,但是如果你去fullOO,你会发现用不同语言编写的例子,包括Ruby和Marvin(第一种为DCI设计的语言)。

编辑“什么是DCI”这个问题没有简单的答案,DCI是一种范式,就像OOP是一种范式。它们都有相同的根源,回答上述问题与回答“什么是面向对象编程”一样复杂。事情变得更加复杂的是,DCI是面向对象的,而所有主要的面向对象语言中的OOP实际上是类导向的而不是面向对象的。DCI旨在产生代码,在运行时对象之间的交互在编译时可见,并且在更一般的术语中试图使从阅读代码推断运行时行为更容易。我上面链接的site专门介绍了DCI的全部内容,并列出了许多语言的示例,其中包括Ruby。

编辑 有一本关于 Ruby 和 DCI 的book即将出版。作者在对象组合方面非常活跃,见解独到。


我必须说,fullOO上的Ruby示例看起来有点奇怪,例如使用线程变量。是否有更接近惯用Ruby的DCI示例,还是那不可能? - Matijs van Zuijlen
@MatijsvanZuijlen,你指的是哪个例子?其中一些使用了gem,而另一些则是用纯Ruby编写的。这个gem修复了一些问题,因为Ruby不支持DCI的作用域规则,但是使用该gem进行调试体验有些欠缺。而纯Ruby示例则违反了DCI的作用域规则,因此两者都是在Ruby中接近DCI的近似实现,但没有一个是真正的DCI(因为在Ruby中不可能实现真正的DCI,尽管你可以非常接近)。 - Rune FS
我只找到了一个例子:http://fulloo.info/Examples/RubyExamples/Dijkstra/DijkstraListing.html - Matijs van Zuijlen
我确信至少有褐色Dijkstra示例。对此很抱歉。您可以在此处找到一些褐色示例:https://github.com/runefs/maroon/tree/master/test/examples。如提交日志所示,我已经很长时间没有在Maroon上做过多的工作,但是至少代码仍然提供了想法。一个更复杂的示例将是Maroon本身。它是完全自举的,也就是说,我使用Maroon编写了Maroon。 - Rune FS
谢谢@rune-fs,这些例子更有意义! - Matijs van Zuijlen

14

对于那些想知道 DCI 是什么的人...

DCI 意为 数据上下文交互


8
DCI的核心是它为开发者提供的认知工具。我不确定你是否看过所有伟大的James Coplien/Trygve Reenskaug演讲,但是我会尝试为任何新接触这些概念的人概括其要点。它关于将系统行为从系统交互领域对象(数据实体或系统本身)中移出,并作为第一类公民放入行为对象(系统所做的事情)中,通过在用例上下文中及时注入功能来协调对象之间的协作。
想想BDD。我们编写的行为不是分散在许多对象中的功能粒子,而是存在于仅用于一个用例(故事)的内聚对象中,并向这些愚蠢的数据对象注入能力并协调它们的交互。就像物理架构的透明层一样,缓慢变化的数据对象没有被装载着始终带着的快速变化的特性实现。相反,Ruby为我们提供了在运行时仅在用例上下文中需要时轻松将行为注入对象的能力。
作为一个ROR的例子,如果您有一个控制器操作涉及事件概率矩阵的用例,在这种情况下,大多数条目可能仅在少量请求中触发,则实例化具有知识执行数据每个可能用例的每个事件的臃肿行为重对象网络是不必要的。此外,将所有逻辑清晰地抽象到上下文对象提供的接口中的模式中,而不需要在我的文本编辑器中查找18个文件以了解该交互如何工作,这也是一个明显的优点。
关于您在Rails中控制器和模型之间添加“另一个”抽象层的问题,我不确定您指的是哪一个。无论如何,是的,可以这样做。没有问题。设计模式和Uncle Bobs' SOLID原则基本上被广泛认为是面向对象设计的最佳实践。它们都强烈鼓励策略和实现之间松耦合的抽象。它们都有助于避免灾难性的大规模思维倒塌,因为它们提供了一个共同的框架,每个人都能理解。对我来说,DCI提供了同样类型的认知框架,但是可以使系统更易于理解和有效地处理,这是任何面向对象设计师的终极目标。

6

有一本关于在Ruby / Rails中使用DCI的书(目前正在进行中):Clean Ruby。我强烈建议将自己放在通知列表上 - 我已经阅读了这本书的部分内容,它看起来非常不错。

在Rails世界中,DCI正在获得认可 - 在过去的三个月左右,已经出现了许多有趣的博客文章。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接