实现域驱动设计的功能方式

时间:2011-01-16 11:12:40

标签: .net f# domain-driven-design

我在使用C#编写域驱动应用程序方面有很多经验。我写的应用程序越多,我发现我想采用的方法与标准的C#/ OO技术不相符:

  1. 我想编写尽可能多的纯函数,因为它们非常容易测试。
  2. 我想以更具声明性的方式编写我的业务逻辑。
  3. 所以我一直在研究F#等函数式语言。毕竟没有理由使用OO实现域驱动设计

    我想知道是否有人在使用功能语言时对域驱动设计设计有任何想法/经验。特别是:

    • 功能域模型会是什么样的?
    • 您如何从域模型中抽象数据访问层。

4 个答案:

答案 0 :(得分:13)

免责声明:我对域驱动设计只有一个模糊的知识,所以答案可能不会使用正确的术语,可能过于专注于代码而不是一般概念,但这里是反正有些想法......

关注理解而不是设计特定的功能或对象来实现它们对于人们如何使用函数式编程语言来说似乎很自然。通常(至少在功能应用程序的一部分中),您首先要设计描述(或模型化)您正在使用的世界的数据结构。数据结构与实现分离,因此很好地模拟了域。

paper about composing financial contracts中描述了一个非常好的例子。该示例是金融合同的估价(和其他处理)申请。最重要的是创建合同模型 - 它们实际上是什么?为了回答这个问题,作者设计了一个描述合同的数据结构。类似的东西:

type Contract = 
  | Zero                         // No trades
  | Single of string * float     // Single trade (buy something for some price)
  | And of Contract * Contract   // Combine two contracts 
  | Until of Contract * DateTime // Contract that can be executed only until...
  // (...)

还有一些其他案例,但数据结构非常简单,并且模拟了金融行业中使用的各种非常复杂的合同。

摘要我认为对用于模拟世界的数据结构的关注(与使用它们的实现分开)非常接近DDD的关键概念。

答案 1 :(得分:5)

使用Clojure(一种现代版本的Lisp)是一种新的想法,它是一种功能语言,用于创建域模型。 This presentation是一个非常好的介绍(它也是HTML5的一个很棒的演示)。

长话短说,功能性态度与Event Sorcing相结合很棒。它可以让您轻松创建完全可测试的模型。如果你现在不想跳入全新的语言,那么现代C#是编写类似函数的代码的一种非常好的语言(至少对于实现通用域模型而言)

答案 2 :(得分:5)

以下是惯用F#实现的示例:Domain-Driven Design With F# and EventStore

免责声明:我是作者。

答案 3 :(得分:2)

古老的问题,但今天仍然令人惊讶。

据我所知,关于功能域驱动设计的最好的(唯一的)书籍是Domain Modeling Made Functional,由F# for fun and profit的作者Scott Wlaschin撰写(如上所述)。

在深入研究本书之前,演讲Functional Programming Design Patterns是对概念的很好总结(提示:没有模式:)

这些示例使用F#语言编写,但它们很容易转换为代数类型的其他任何功能语言(在我的案例中为Haskell和PureScript)。