网上看到一个gradle和maven对比的例子:
maven的代码如下:
2.3
com.google.code.kaptcha
kaptcha
${kaptcha.version}
jdk15
org.springframework
spring-core
org.springframework
spring-beans
org.springframework
spring-context
junit
junit
gradle脚本如下:
dependencies {
compile('org.springframework:spring-core:2.5.6')
compile('org.springframework:spring-beans:2.5.6')
compile('org.springframework:spring-context:2.5.6')
compile('com.google.code.kaptcha:kaptcha:2.3:jdk15')
testCompile('junit:junit:4.7')
}
然后说代码由28行变成了惊人的7行。嗯这点我得承认,光从最简单的依赖简洁度上面来说gradle确实很优秀,这几行代码的可读性确实比maven的可读性高了不只一点半点,但是编码速度这几行并没有啥提高,因为maven的xml在它xsd文件的约束下,结合ide工具的自动提示功能,很容易查找到自己标签对以及文字。而因为gradle的太过灵活,反而减弱了代码的自动提示功能。
举个例子,我们要引用下面的依赖:'org.mybatis:mybatis:3.4.5'
在gradle下面请问哪种写法方式是错误的:
a.compile 'org.mybatis:mybatis:3.4.5'
b.compile('org.mybatis:mybatis:3.4.5')
c.compile group: 'org.mybatis', name: 'mybatis', version: '3.4.5'
d.compile (group: 'org.mybatis', name: 'mybatis', version: '3.4.5')
答案是没有一种错误,所以对于ide来说,不输入任何字符的情况下我是提示你输入单引号呢,还是双引号呢,还是左括号呢,还是group属性呢,ide蒙圈了。但是在maven下面就不会存在,因为只有一种情况。另外,现在大多数ide还不支持gradle自动提示,或者是不完善。在eclipse中我gradle只有语法高亮,其它功能就没有了。在vs中在插件的支持下提示很强大但是也不完善:就拿编译时机这几个函数单词来说:vs收录了这几个单词:
而我遇见的编译函数或者应该遇见的还有:
如此多的一义多词,和一词多义往往也导致我们头大,到底我该用哪一个,而maven的情况就少得多了
gradle并不简洁,主要体现在多项目上
现在我有四个项目分别为:
a.travelcode-common 不依赖其它任何项目,用于公共代码的书写
b.travelcode-autoconfig 只依赖travelcode-common,用于做spring相关的自动配置
c.travelcode-autoconfig-stater 只依赖travelcode-autoconfig用于管理travelcode-autoconfig自动配置的jar包
d.travelcode-uam 业务项目,依赖abc三个包
好了我们现在说下gradle不简洁在哪里
1.setting.gradle文件的include不简洁
b项目的include代码
c项目的include代码
d 项目的including代码
是不是很蛋疼,每个子项目都要重复的include父项目及父父项目及父父父项目,难道我就不能简单的写成下面这样,然后你根据setting链条去找么,比如下面这种写法
b项目的include代码
c项目的include代码
d 项目的including代码
可实际上这种写法根本不行,假如d少了includeFlat "travelcode-common" 这句代码 ,d项目构建时就会喊:“喂,骚年travelcode-autoconfig 依赖的"travelcode-common" 包找不到呀”,我只能骂娘的说:"你就不能问问travelcode-autoconfig 项目"travelcode-common" 项目在什么地方蹲着呀?"可是这货就是你不告诉它在什么位置他就是找不到,所以如果按照maven数据链的方式打包,你就得记住一大堆依赖关系
2.build.gradle不简洁:
因为我时采用maven一样的数据链依赖关系,所以每个build,gradle文件都有下面一段代码:
然而这种问题在maven中就好处理了,直接一个parent搞定。
好了这时候肯定有人会站出来说:“骚年,maven是maven,gradle是gradle,maven采用的是子孙相传数据链的方式,而gradle多项目依赖采用的是多子多福枝繁叶茂的方式,有一个根就够了”比如上面4个项目我可以再建立一个项目叫做travelcode-multis 把d项目(travelcode-uam)setting.gradle的include部分复制到travelcode-multis 的setting.gradle文件中,然后所有的abcd项目的setting文件的include部分可以删除了,然后将build,gradle的公共部分放到travelcode-multis 中处理,现在abcd四个项目的所以公共部分都可以删除了,基本只剩下dependencies 部分了,甚至连dependencies 部分都可以没有,也就是子项目build.gradle都可以没有够简洁吧。
可是问题来了,简洁是简洁了,可是现在儿子做什么事情都得经过父亲同意了:儿子想要变成jar包,父亲说:"儿子这些事情不用你来做,我来帮你,再说你自己知道怎么变身不。"儿子想要分家:"父亲说你怎么这么忤逆呢,既然你坚持我就把你从我族谱上除名了,"然后父亲将儿子从setting文件中删除,以及builde,gradle中关于这个儿子的一切记忆也得删除,因为不删除父亲就患得患失呀,没心情管理其它儿子的事情了,一编译就抱怨我有个儿子不再了。好了儿子从我的项目中除名了,要成家立业,之前父亲做的事情,我也得会做呀。于是你重新写配置文件吧,父亲怎么做的你怎么做!这时候其它儿子因为之前这个儿子比较好相处,所有的人都和这个儿子在未经父亲同意的情况下建立了关系,这时候这个儿子突然从父亲族谱上面除名了,所以这些儿子想继续维持和这个儿子的关系的话,必须单独建立关系,写到自己的关系网中,所以每个儿子都得写关系网。
还有为了让更多的程序员来晚上这个大家庭,所以所有的家庭成员都加入了svn这个大组织,可是这时候出现一个问题是,每个程序员必须找齐这个家庭的每一个成员,才能够动工,不然父项目的分身就会抱怨我这个儿子不见了,那个儿子不见了。如果A程序员告诉这个父项目的A分身,你哪个儿子对我没用,你直接从你族谱除名吧,然后这个父亲的分身真这么干了,可是另外的程序员对父亲的另外一个B分身说,你其它儿子不用,我就要A程序没用的那个儿子,于是所有儿子都从B分身除名了,B分身只剩下A程序员那个没用的儿子。后来到了战绩汇总的时候,所有程序员都提交代码了,这时候发现冲突了。父项目A分身和父项目B分身撕逼大战开始了。
综合起来,gradle的父亲是为儿子操碎了心。最后心力交瘁,却导致了程序员猝死。
而maven的父项目就是什么也不管,只告诉子项目我有哪些遗产,你拿去,至于怎么处理你看着办,要就留着,不要就扔掉,当然除了部分强制你要的留下就行,还有具体怎么做你看着办,我不管,撕逼的事情跟我没关系,你自己去处理,我把家规定下来就行。只要你们依照规矩办事,不会出错。程序员撕逼你找我儿子去。
gradle本身不存在版本控制,可能他觉得,什么事情都是我亲历亲为了还需要什么版本控制呀!即使有版本控制,也是靠插件来完成的,比如我上面是个项目中gradle的版本控制就是依靠'org.springframework.boot' 来完成的,然后才有这段代码
不然gradle就会说dependencyManagement 什么鬼,问题是大多数程序员并不会写插件,我也是。而且会写也觉得麻烦呀,而maven就是靠dependencyManagement 订立的规矩。
而maven在处理上面的问题就简单多了,唯一的缺点是maven的xml配置确实不够简洁,如果把maven的xml语法改成类json语法,我们再来比一比谁跟简洁,就像下面这代码:
//复杂版本
//简洁版本
如果maven这样,你还觉得gradle有优势么,这样maven就少了一半的代码