Rob*_*ill 7 android gradle multi-module android-gradle-plugin
这是不是之间的区别的常见问题api和implementation,并希望将但从构建一个多模块项目的点更先进的和有趣的.
假设我在应用程序中有以下模块
librarybasefeature1feature2app现在模块之间的关系是:
base 包装 library
feature1并feature2使用(取决于)base
app拼feature1和feature2
这个多模块结构中的所有内容都应该能够使用Gradle的implementation依赖项工作,并且不需要在api任何地方使用该子句.
现在,让我们说feature1需要访问base包含在其中的实现细节library.
为了使library提供给feature1我们有两个选择,据我可以告诉:
更改implementation为api在base泄漏依赖于依赖模块base
library作为implementation依赖项添加,feature1而不会base泄漏依赖性library
当然,为了解决这个问题,这个例子已经被简化了,但是你明白了这可能会成为一个具有4或5级依赖关系的大量模块的配置地狱.
我们可以创建一个base-feature中间模块,它可以包装base并提供另一级抽象,以便feature1在不泄漏的情况下使用library,但让我们将该解决方案置于此问题的范围之外,以专注于依赖项的设置.
我在上述选项中检测到的一些权衡:
选项1)专业人士
build.gradle的文件,因为不需要重复implementation条款api子句进行单个更改,并查看传播到所有使用者模块的更改选项1)缺点
选项2)专业人士
选项2)缺点
implementation必须修改包含该子句的所有模块.即使我认为这是一件好事,因为它完全跟踪变更如何修改项目,我看到它可能需要更多时间.现在的问题是:
在编译这个多模块场景时是否有任何权衡取舍?
是否一个模块泄漏依赖"更快"以便为消费者模块编译?
它在构建时间方面有很大差异吗?
我还缺少哪些其他副作用,利弊?
谢谢你的时间.
从Gradle论坛主题重新发布。
您所描述的是关于分层体系结构系统的相当普遍的讨论,也称为“严格”层与“松散”层,或“开放”层与“封闭”层。请参阅《软件体系结构模式》中的这一章(也希望对您免费),以了解一些符号学,这些符号学不太可能对您的选择有很大帮助
从我的角度来看,如果模块需要中断分层,则可以对项目结构进行建模,以最直接,最直观的方式展示它。在这种情况下,这意味着将添加library为的实现依赖项feature1。是的,它使图表更丑陋,是的,它迫使您在升级时触摸几个文件,这就是重点-您的设计有缺陷,现在可以看到。
如果很少有模块需要以相同的方式破坏层封装,我可以考虑添加一个单独的基本模块来公开该功能,其名称为base-xyz。添加新模块是一件大事,不是因为技术上的工作,而是因为我们的大脑一次只能处理这么多的“事物”(块)。我相信,当Gradle“变体”可用时,也是如此,但是由于我还没有尝试过,所以我不能断言。
如果base模块的所有客户端都需要访问library(即,因为您使用library公共签名中的类或异常),则应将libraryAPI 公开为base。缺点是library成为的公共API的一部分base,它可能比您想要的更大,并且不受您的控制。公共API是您要负责的事情,并且您希望使其保持小巧,文档化和向后兼容。
在这一点上,您可能正在考虑拼图模块(好的),osgi(错误的……不要),或者将需要公开的lib部分包装在自己的类中(也许吗?)
只为打破依赖关系而包装并不是一个好主意。一方面,它增加了您维护(以及希望)文档的代码量。如果您开始在该base层中进行少量修改,并且该library库是众所周知的库,则会引入(增值)不一致-必须始终警惕它们对lib的假设是否仍然成立。最后,薄包装器通常最终会泄漏库设计,因此,即使它们包装了API,当替换/升级lib时,仍然会迫使您触摸客户端代码,这时最好直接使用lib。
因此,正如您所看到的,是权衡和可用性。CPU不在乎模块边界在哪里,并且所有开发人员都不相同-有些可以更好地应对大量简单的事情,有些可以更好地应对少数高度抽象的概念。
当任何好的设计都可行时,不要着迷于最好的设计(就像鲍勃叔叔会做的那样)。为引入顺序而辩解的额外复杂性的数量是一个模糊的数量,您可以自行决定。给您最好的电话,不要害怕明天更改它:-)
| 归档时间: |
|
| 查看次数: |
844 次 |
| 最近记录: |