像鲍勃大叔那样的 Clojure 架构
Clojure Architecture like Uncle Bob did
我正在尝试实现 Clojure 架构,就像 Bob 叔叔在那里所做的那样 http://blog.8thlight.com/uncle-bob/2012/08/13/the-clean-architecture.html 并且就像他在第 07 集 - 架构、用例和高级设计中用干净的代码描述的那样。
Nothing in an inner circle can know anything at all about something in
an outer circle.
我想用所有业务规则和测试编写应用程序的核心代码。这个核心必须定义数据库中 "objects" 的操作,如用户、支付、广告等。但是如何实现这些操作必须在更高级别的应用程序上进行。
所以问题是:你能给我一个在 github 上很好的架构应用的例子吗? 我正在学习 Clojure,我想看看如何在技术上做到这一点。我正在尝试自己做,但结果很糟糕。简单的代码示例将对我有很大帮助。 我想知道如何在 Clojure 中像在图像上一样逐步创建图层。
如果能提供有关如何在 Clojure 中高质量地完成这项工作的任何信息,我将非常高兴。可以是代码、视频或文章。可以免费也可以买。
Bob 大叔的干净架构的关键要素是依赖倒置。使用 Clojure 有多种方法可以实现这一点:使用高阶函数和协议可能是最相关的两种(blog post of mine on dependency inversion in Clojure 的无耻插件)。例如,您可以为您的数据定义一个持久性协议,它完全不知道特定的实现:
(defprotocol MyDataDao
(load-data [])
(save-data []))
然后你可以实现所述协议,它可以使用数据库或普通文件系统(注意:使用 reify
只是一个选项):
(defn make-mydata-db-dao []
[... db-setup-code ... ]
(reify MyDataDao
(load-data []
[... data-query-code ...])
(save-data []
[... data-save-code ...])))
与其手工制作 make-mydata-db-dao
,不如看看 Stuart Sierra 出色的作品 component library。
但是,您还需要实现不同的圈子:这基本上是一个使用名称空间并确保将例如协议定义进入右内层circles/layers,实现进入正确的外层。
让我们假设您的网关代码通常位于命名空间 app.gateway.*
中。那么协议 MydataDao
可能会在命名空间 app.gateway.dao
中结束。虽然实施属于不同的外圈。假设您所有的数据库代码都在命名空间 app.db.*
中,那么您可以将 make-mydata-db-dao
放入 app.db.dao
.
不幸的是,我不知道 Clojure 中有任何现有代码库可以彻底实现这一点。实际上,我很想看到一个以任何语言实现的真实示例,并更多地了解使用它的优缺点或困难。
我正在尝试实现 Clojure 架构,就像 Bob 叔叔在那里所做的那样 http://blog.8thlight.com/uncle-bob/2012/08/13/the-clean-architecture.html 并且就像他在第 07 集 - 架构、用例和高级设计中用干净的代码描述的那样。
Nothing in an inner circle can know anything at all about something in an outer circle.
我想用所有业务规则和测试编写应用程序的核心代码。这个核心必须定义数据库中 "objects" 的操作,如用户、支付、广告等。但是如何实现这些操作必须在更高级别的应用程序上进行。
所以问题是:你能给我一个在 github 上很好的架构应用的例子吗? 我正在学习 Clojure,我想看看如何在技术上做到这一点。我正在尝试自己做,但结果很糟糕。简单的代码示例将对我有很大帮助。 我想知道如何在 Clojure 中像在图像上一样逐步创建图层。
如果能提供有关如何在 Clojure 中高质量地完成这项工作的任何信息,我将非常高兴。可以是代码、视频或文章。可以免费也可以买。
Bob 大叔的干净架构的关键要素是依赖倒置。使用 Clojure 有多种方法可以实现这一点:使用高阶函数和协议可能是最相关的两种(blog post of mine on dependency inversion in Clojure 的无耻插件)。例如,您可以为您的数据定义一个持久性协议,它完全不知道特定的实现:
(defprotocol MyDataDao
(load-data [])
(save-data []))
然后你可以实现所述协议,它可以使用数据库或普通文件系统(注意:使用 reify
只是一个选项):
(defn make-mydata-db-dao []
[... db-setup-code ... ]
(reify MyDataDao
(load-data []
[... data-query-code ...])
(save-data []
[... data-save-code ...])))
与其手工制作 make-mydata-db-dao
,不如看看 Stuart Sierra 出色的作品 component library。
但是,您还需要实现不同的圈子:这基本上是一个使用名称空间并确保将例如协议定义进入右内层circles/layers,实现进入正确的外层。
让我们假设您的网关代码通常位于命名空间 app.gateway.*
中。那么协议 MydataDao
可能会在命名空间 app.gateway.dao
中结束。虽然实施属于不同的外圈。假设您所有的数据库代码都在命名空间 app.db.*
中,那么您可以将 make-mydata-db-dao
放入 app.db.dao
.
不幸的是,我不知道 Clojure 中有任何现有代码库可以彻底实现这一点。实际上,我很想看到一个以任何语言实现的真实示例,并更多地了解使用它的优缺点或困难。