Gradle大吐槽

 gradle是啥我不说了。我今天是来吐槽的!吐槽的!

1.gradle简洁而不高效

网上看到一个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收录了这几个单词:

compile
compileClasspath
compileOnly
testCompile
testCompileClasspath
testCompileOnly
testRuntime
runtime

而我遇见的编译函数或者应该遇见的还有:

api
provide
providedCompile
implement

如此多的一义多词,和一词多义往往也导致我们头大,到底我该用哪一个,而maven的情况就少得多了

2.gradle并不简洁

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代码

includeFlat "travelcode-common"

c项目的include代码

includeFlat "travelcode-autoconfig"
includeFlat "travelcode-common"

d 项目的including代码

includeFlat "travelcode-autoconfig"
includeFlat "travelcode-common"
includeFlat "travelcode-autoconfig-stater"

是不是很蛋疼,每个子项目都要重复的include父项目及父父项目及父父父项目,难道我就不能简单的写成下面这样,然后你根据setting链条去找么,比如下面这种写法

b项目的include代码

includeFlat "travelcode-common"

c项目的include代码

includeFlat "travelcode-autoconfig"

d 项目的including代码

includeFlat "travelcode-autoconfig-stater"

可实际上这种写法根本不行,假如d少了includeFlat "travelcode-common"  这句代码 ,d项目构建时就会喊:“喂,骚年travelcode-autoconfig 依赖的"travelcode-common" 包找不到呀”,我只能骂娘的说:"你就不能问问travelcode-autoconfig 项目"travelcode-common" 项目在什么地方蹲着呀?"可是这货就是你不告诉它在什么位置他就是找不到,所以如果按照maven数据链的方式打包,你就得记住一大堆依赖关系

2.build.gradle不简洁:

因为我时采用maven一样的数据链依赖关系,所以每个build,gradle文件都有下面一段代码:

buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath( "org.springframework.boot:spring-boot-gradle-plugin:1.5.9.RELEASE")
}
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'

jar {
baseName = 'travelcode-uam'
version = '0.0.1'
from( 'src/main/java') {
include '**/*'
}
from( 'src/main/resources') {
include '**/*'
}
}

repositories {
mavenCentral()
maven { url "https://repo.spring.io/snapshot" }
    maven { url "https://repo.spring.io/milestone" }
}
dependencyManagement {
    imports {
        mavenBom "org.springframework.cloud:spring-cloud-dependencies:Edgware.SR2"
    }
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'

          然而这种问题在maven中就好处理了,直接一个parent搞定。

3.华而不实的简洁

     好了这时候肯定有人会站出来说:“骚年,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的父项目就是什么也不管,只告诉子项目我有哪些遗产,你拿去,至于怎么处理你看着办,要就留着,不要就扔掉,当然除了部分强制你要的留下就行,还有具体怎么做你看着办,我不管,撕逼的事情跟我没关系,你自己去处理,我把家规定下来就行。只要你们依照规矩办事,不会出错。程序员撕逼你找我儿子去。

4.gradle版本控制不存在的

gradle本身不存在版本控制,可能他觉得,什么事情都是我亲历亲为了还需要什么版本控制呀!即使有版本控制,也是靠插件来完成的,比如我上面是个项目中gradle的版本控制就是依靠'org.springframework.boot' 来完成的,然后才有这段代码

 

dependencyManagement {
    imports {
        mavenBom "org.springframework.cloud:spring-cloud-dependencies:Edgware.SR2"
    }
}

不然gradle就会说dependencyManagement 什么鬼,问题是大多数程序员并不会写插件,我也是。而且会写也觉得麻烦呀,而maven就是靠dependencyManagement 订立的规矩。  

而maven在处理上面的问题就简单多了,唯一的缺点是maven的xml配置确实不够简洁,如果把maven的xml语法改成类json语法,我们再来比一比谁跟简洁,就像下面这代码:

//复杂版本

{
"parent": {
"groupId": "org.springframework.cloud",
"artifactId": "spring-cloud-commons-parent",
"version": "1.3.2.RELEASE"
},
"artifactId": "spring-cloud-starter",
"name": "spring-cloud-starter",
"description": "Spring Cloud Starter",
"url": "https://projects.spring.io/spring-cloud",
"organization": {
"name": "Pivotal Software, Inc.",
"url": "https://www.spring.io"
},
"properties": [
{ "main.basedir": "${basedir}/../.."},
{ "main.basedir1": "${basedir1}/../.."},
{ "main.basedir2": "${basedir2}/../.."}
],
"dependencies": [
{
"dependency": {
"groupId": "org.springframework.boot",
"artifactId": "spring-boot-starter",
"version": "1.5.9.relase"
}
}
]
}

//简洁版本

{
"parent": "org.springframework.cloud:spring-cloud-commons-parent:1.3.2.RELEASE",
"artifactId": "spring-cloud-starter",
"name": "spring-cloud-starter",
"description": "Spring Cloud Starter",
"url": "https://projects.spring.io/spring-cloud",
"organization": [ "Pivotal Software, Inc.", "https://www.spring.io"],
"properties": [
{ "main.basedir": "${basedir}/../.."},
prop{ "main.basedir1": "${basedir1}/../.."},
[ "main.basedir2" : "${basedir2}/../.."]
],
"dependencies": [
dependency( "org.springframework.boot", "spring-boot-starter", "1.5.9.relase" ),
complic( "org.springframework.boot1", "spring-boot-starter1", "1.5.9.relase" ),
[ "org.springframework.boot1", "spring-boot-starter1", "1.5.9.relase"],
"org.springframework.boot1:spring-boot-starter1:1.5.9.relase"
]
}

如果maven这样,你还觉得gradle有优势么,这样maven就少了一半的代码

你可能感兴趣的:(技术方案)