idea如何把包变为模块_让我们将包变成模块系统!
idea如何把包变为模块
使用构建系统将许多项目分为模块/子项目( Maven , Gradle , SBT …); 编写模块化代码通常是一件好事。 将代码分为构建模块主要用于:
- 隔离代码部分(减少耦合)
- api / impl拆分
- 仅将第三方依赖项添加到代码的特定部分
- 具有相似功能的代码分组
- 静态检查一个模块中的代码仅使用其依赖模块(模块间依赖)中的代码
尽管有些人可能说它对于单独的编译也很有用,但我认为这并不重要(考虑一个项目时)。 如今,构建工具非常聪明,可以找出需要重新编译的内容。
构建模块问题
我认为这种方法存在一些问题。 首先,很难确定何时某个功能“足够大”以将其转换为构建模块。 几门课就够了吗? 还是您需要更多? 严格来说,每个模块是否应该只有一种功能? 但这会导致模块爆炸。 等等。 至少在我参与的项目中,这是讨论的共同主题,即构建模块的粒度应如何粗略。
其次,构建模块非常“繁重”。 我想Maven最糟糕,您需要大量的xml来创建一个带有大量样板文件的模块(例如,重复的组ID,版本号,父级定义); SBT和Gradle更好,但仍然是一项巨大的努力。 需要创建一个单独的目录,整个目录结构( src/main/...
, src/test/...
),更新构建配置等。总的来说,这很麻烦。
然后,当我们将漂亮的模块分开时,经常会发现,为了使它们中的两个相互协作,我们需要一个“通用”部分。 然后,我们要么以一个肿的foo-common模块结束,该模块包含不相关类的负载,要么以多个小型foo-foomodule-common模块结束; 第二种解决方案当然没问题,只是浪费时间进行设置。
最后,构建模块是您还必须命名的其他内容。 软件包名称和类名称很可能已经反映了代码的作用,现在还需要在构建模块名称中重复(违反DRY)。
总而言之,我认为创建构建模块非常困难且耗时。 程序员是懒惰的(当然,这是一件好事),这导致设计不像它们可能的那么干净。 是时候改变它了:)
(另请参见我之前有关模块的博客 。)
配套
Java,Scala和Groovy已经有一个用于对代码进行分组的系统:程序包。 但是,当前包仅是字符串标识符。 除了一些非常有限的可见性选项(在Java中为package-private,在Scala中为package-scoping)之外,软件包没有语义。 因此,我们有几个级别的分组代码:
- 项目
- 构建模块
- 包
- 类
如果我们将2.和3.合并在一起会怎样? 为什么不应该使用软件包来创建模块?
包作为模块?
让我们来看看将包扩展为模块会怎样。 显然,我们需要做的第一件事是将一些元数据与每个模块相关联。 已经有一些机制(例如,通过package-info.java
上的注释),或者这可能是Scala中软件包对象的扩展-可以混入某些特征,或覆盖val 。
什么样的元数据? 当然,我们不想将整个构建定义移到软件包中。 但是让我们分开关注 –构建定义应该定义如何构建项目,而不是模块依赖项。 然后,在模块的元数据中定义的第一件事就是对第三方库的依赖。 这样的定义可能只是符号,它将被绑定到构建定义中的具体版本。
例如,我们将指定包“ foo.bar.dao
”取决于“ jpa
”库。 然后,构建定义将包含从“ jpa
”到Maven工件列表的映射(例如hibernate-core,hibernate-entitymanager等)。 而且,如果这种依赖关系可以传递到子包,则可能最有意义。 因此,定义全局库将意味着增加对根包的依赖。
附带说明一下,通过扩展Scala的包对象,甚至可以将其设置为类型安全的。 包对象可以实现特征,其中要覆盖的值之一可以是第三方依赖项符号的列表。 符号本身可以包含在根包中定义的Enumeration
中; 这可以使诸如“根据jpa查找所有模块”之类的事情在IDE中进行简单的用法搜索。
第二步是也使用此机制定义模块间依赖关系。 在包的元数据中,可以定义其他包的列表,从中可以看到代码。 这遵循当前构建模块的使用方式:每个构建模块均包含可访问的项目模块的列表。 (另一个Scala旁注:由于包对象将实现特征,这意味着定义具有给定类型的对象列表。)
更进一步,我们可以指定api和impl类型包。 默认情况下,可以从其他软件包访问Api型的。 另一方面,如果不将Impl类型的程序包明确指定为依赖项,则无法访问它们。
在实践中看起来如何? Scala中的一个非常粗糙的草图:
package foo.user// Even without definition, each package has an implicit package object
// implementing a PackageModule trait ...
package object dao { // ... which is used here. The type of the val below is // List[PackageModule].override val moduleDependsOn = List(foo.security, foo.user.model) override val moduleType = ModuleType.API// FooLibs enum is defined in a top-level package or the build systemoverride val moduleLibraries = List(FooLibs.JPA)
}
重构
重构是日常活动; 但是,重构模块通常是一项艰巨的任务,有时只能使用一次。 应该是这样吗? 如果将程序包扩展到模块,则重构模块将与四处移动和重命名程序包相同,另外还需要更新元数据。 这将比现在容易得多,我认为这将导致更好的总体设计。
建立系统
上面的内容显然意味着构建系统需要做更多的工作–很难弄清模块列表,构建顺序,要创建的工件列表等(顺便说一句,如果要为一个程序包创建一个单独的jar,可以也是元数据的一部分)。 此外,还需要进行一些验证-循环依赖关系,或试图以错误的方式限制可见性。
但是后来,人们做了比这更复杂的软件
拼图?
您可能会说,这与项目Jigsaw重叠,后者将在Java 9中(或不是)中出现。 但是,我认为Jigsaw的目标范围不同:项目级别的模块。 因此,一个拼图模块将是您的整个项目,而您将拥有多个(数十个)程序包模块。
名称“模块”在这里是重载的,也许名称“迷你模块”会更好,或者适度地“正确地打包”。
底线
我认为,当前定义构建模块的方法太过困难且受限制。 另一方面,将包装提升至模块将非常轻巧。 定义一个新模块与创建一个新程序包相同–简单得多。 第三方库只能在需要的地方添加。 少说一件事。 每个项目只有一棵源树。
同样,这种方法可以根据项目需求进行扩展和调整。 无需花费太多精力就可以定义细粒度模块或粗粒度模块。 甚至更好的是,为什么不创建两个模块呢?模块可以嵌套并在另一个模块之上构建。
现在…唯一的问题是实现并添加IDE支持;)
参考: 让我们将包变成模块系统! 来自我们的JCG合作伙伴 Adam Warski, 网址为Adam Warski博客。
翻译自: https://www.javacodegeeks.com/2012/11/lets-turn-packages-into-a-module-system.html
idea如何把包变为模块
idea如何把包变为模块_让我们将包变成模块系统!相关推荐
- py导入包异常跳出_马克的Python学习笔记#模块和包
把模块按层次结构组织成包 模块和包是任何大型项目的核心,就连Python安装程序它本身也是一个包.创建一个软件包结构是非常简单的,我们只要把代码按照我们所希望的方式在文件系统上进行组织并且确保每个目录 ...
- python 查看已经安装的模块_教你用Python查看模块的帮助文档,方法和帮助信息...
这里介绍下python自带的查看帮助功能,可以在编程时不中断地迅速找到所需模块和函数的使用方法 查看方法 通用帮助函数help() python中的help()类似unix中的man指令,熟悉后会对我 ...
- python 命令行 模块_深入浅析Python 命令行模块 Click
Click 是用 Python 写的一个第三方模块,用于快速创建命令行.我们知道,Python 内置了一个 Argparse 的标准库用于创建命令行,但使用起来有些繁琐,Click 相比于 Argpa ...
- ping 丢包 网络摄像头_网络监控摄像机丢包的原因分析
原标题:网络监控摄像机丢包的原因分析 引文 不少人在使用网络和监控摄像系统的时候都有遇到过数据丢包的情况,数据丢包的原因是多种多样的,以下就为大家介绍一下网络数据丢包的原因及摄像机丢包的原因. 原因分 ...
- 光纤传感器实验模块_光纤传感器实习模块_实习3振动丈量试验模块doc
自动化专业好吗凭据图安置连合线.贯注电涡流断面与振动台面之间的安置隔绝为线性区域.试验模块输出端TP3接示波器接入±12V电源. 信号源幅度按钮初始为零缓慢增大幅度独揽台面与传感器端面不要碰撞. 用示 ...
- node.js中模块_在Node.js中需要模块:您需要知道的一切
node.js中模块 by Samer Buna 通过Samer Buna 在Node.js中需要模块:您需要知道的一切 (Requiring modules in Node.js: Everythi ...
- python如何查看有什么模块_在python中如何查看模块功能
在python中查看模块功能的方法:1.在python命令行输入help()函数进入help帮助文档界面:2.键入[modules]列出当前所有安装的模块:3.键入相应的模块名称即可得到该模块的功能信 ...
- python如何导入自定义模块_【python】导入自定义模块
一.直接import 1.当执行文件与要导入的py文件在同一目录下时 假设要在wangyi.py中导入weibo.py文件 import weibo 2.当执行文件与要导入的py文件所在文件夹在同一目 ...
- python导入自定义模块_如何Import自定义的Python模块?
原标题:如何Import自定义的Python模块? 实际工作中,经常要用的功能能不能像导入python模块一样,通过import导入呢?答案当然是可以的,本文教你如何做,大家一起来学习吧! 背景 在实 ...
最新文章
- 致被套基民:老基民的四点教训七点经验(ZT)
- Response.Redirect 打开新窗口的两种方法
- 处理机调度实验c语言,操作系统实验处理机调度C语言实现
- 注册了一个域名WELAI.NET
- Keepalived+Nginx 实现双机热备
- spring——使用注解声明式事务整合jdbc——GRUD
- 空间谱专题16:信号个数估计
- 前端学习(3349):数组方法的运用和数值
- 前端学习(2150):webpack之配置babel
- HDU5765 Bonds 最小割极
- Intel超线程技术 Hyper-Threading Technology (6) - 后期增强(Nehalem/Haswell/Skylake)
- DataTable/DataSet汇出Excel
- Linux磁盘下面有个mpatha,Linux中如何使用vmstat命令
- [转载]fft-matlab 补零对结果影响的讨论
- 商务谈判中有哪些谈判技巧?
- iconv php gbk utf8,PHP通过iconv将字符串从GBK转换为UTF8字符集
- oracle ebs 简介
- Servlet中的监听器与过滤器的详细介绍
- 【0024】互联网创业的地域鄙视链
- 个人关于高考志愿填报的一丁点儿看法
热门文章
- 【JVM】浅谈双亲委派和破坏双亲委派
- Java开发必会的反编译知识
- 算法二之树形选择排序
- JS中数组的常用方法
- 强行覆盖远程的gitlab 出错
- dd命令打包多个文件_linux的tar命令详情;linux多个文件压缩打包到一个压缩文件...
- python渐变色代码_如何在Python中创建颜色渐变?
- MySQL的CRUD操作+使用视图
- packt_Packt和Java Code Geeks提供的$ 5 Java编程书籍!
- javaone_JavaOne 2015:高级模块化开发