mik*_*era 15 clojure circular-dependency
我的工作有不同的命名空间之间的一些循环依赖一些Clojure的代码,我试图找出解决这些问题的最佳途径.
有什么想法吗?在Clojure中处理这种循环依赖的最佳方法是什么?
Mic*_*zyk 24
我记得Clojure中有关命名空间的一些讨论 - 在邮件列表和其他地方 - 我必须告诉你,共识(和AFAICT,当前Clojure设计的方向)是循环依赖是一个设计的呼声重构.偶尔可能会有变通方法,但是丑陋,可能会对性能造成问题(如果你让事情变得不必要"动态"),不能保证永远工作等等.
现在你说循环项目结构很好,模块化.但是,如果一切都依赖于一切......为什么你会这么称呼呢?此外,如果您提前计划树状依赖结构,那么"每次有依赖性来解决"都不应该经常发生.为了解决将一些基本协议等放在自己的命名空间中的想法,我不得不说很多时候我都希望项目能够做到这一点.我发现它有助于我浏览代码库并快速了解它正在使用什么类型的抽象.
总而言之,我的投票是重构.
Ham*_*aya 14
我有一些类似gui代码的问题,我最终做的是,
(defn- frame [args]
((resolve 'project.gui/frame) args))
Run Code Online (Sandbox Code Playgroud)
这允许我在运行时解析调用,这是从帧中的菜单项调用,所以我100%确定帧是定义的,因为它是从帧本身调用的,请记住,resolve可能返回nil.
我经常遇到同样的问题.尽管许多开发人员不愿意承认这一点,但这是该语言中一个严重的设计缺陷.循环依赖是真实对象的正常条件.没有心脏,身体就无法生存,没有身体,心脏就无法生存.
可以在呼叫时解决,但这不是最佳的.假设你有一个API,作为api的一部分是错误报告方法,但是api创建了一个有自己方法的对象,这些对象需要报告错误,你有循环依赖.错误检查和报告功能将经常被调用,因此在调用它们时解析不是一种选择.
在这种情况下,大多数情况下,解决方案是将没有依赖关系的代码移动到可以自由共享的独立(util)命名空间中.我还没遇到过用这种技术无法解决问题的情况.这使得维护完整,功能性的业务对象几乎不可能,但它似乎是唯一的选择.Clojure还有很长的路要走,它是一种能够精确建模现实世界的成熟语言,直到那时以不合逻辑的方式划分代码才是消除这些依赖关系的唯一方法.
如果Aa()依赖于Ba()和Bb()依赖于Ab(),唯一的解决方案是将Ba()移动到Ca()和/或Ab()移动到Cb(),即使C在技术上不存在于现实中.
| 归档时间: |
|
| 查看次数: |
6669 次 |
| 最近记录: |