换个视角看 Maven:一个领域平台的优美设计 - 开源中国社区
换个视角看 Maven:一个领域平台的优美设计
小云栖 2016年01月19日

换个视角看 Maven:一个领域平台的优美设计

小云栖 小云栖 发布于2016年01月19日 收藏 225 评论 16

腾讯云 十分钟定制你的第一个小程序>>>  

作为一个Java程序员,Maven是再熟悉不过的工具了, 它提供了构建项目的一个框架, 在默认情况下为我们提供了许多常用的Plugin,其中便包括构建Java项目的Plugin,还有War,Ear等。除此之外还提供内建的项目生命周期管理。 
20140824202302102

以上是我们最熟悉的maven的一面。 下面我们要从领域平台设计的角度,分析Maven的优美设计,为我们做领域平台化提供参考,最后我们再来思考如何做招商的领域平台。

Maven是领域驱动设计实现的,作为一个强大的项目管理构建平台而实现

我们先会介绍maven的基本模型,概念以及功能。 然后我们在分析这个领域平台在领域设计上的一些亮点。最后我们再延伸思考,如果用maven的思路我们可以在阿里的业务系统平台化中得到什么启示。

Maven的用途,核心概念,用法,扩展等

Maven的基本介绍

Maven 是 Apache 组织下的一个通用项目管理工具,它主要用来帮助实现项目的构建、测试、打包和部署。Maven 提供了标准的软件生命周期模型和构建模型,通过配置就能对项目进行全面的管理。它Maven 将构建的过程抽象成一个个的生命周期过程,在不同的阶段使用不同的已实现插件来完成相应的实际工作,这种设计方法极大的避免了设计和脚本编码的重复,极大 的实现了复用。

Maven的核心概念

  1. POM

    这是Maven最重要的一个概念, pom是指project object Model。pom是一个xml,在maven2里为pom.xml。是maven工作的基础,在执行task或者goal时,maven会去项目根目录下读取pom.xml获得需要的配置信息

    这个POM,就是maven平台的领域对象。 Maven就是围绕这个POM领域对象构建起来的领域平台。

    pom文件中包含了项目的信息和maven build项目所需的配置信息,通常有项目信息(如版本、成员)、项目的依赖、插件和goal、build选项等等

    pom是可以继承的,通常对于一个大型的项目或是多个module的情况,子模块的pom需要指定父模块的pom

    pom文件中节点含义如下:

    project

    pom文件的顶级元素

    modelVersion

    所使用的object model版本,为了确保稳定的使用,这个元素是强制性的。 除非maven开发者升级模板,否则不需要修改

    groupId

    是项目创建团体或组织的唯一标志符,通常是域名倒写,
    如groupId  org.apache.maven.plugins就是为所有maven插件预留的

    artifactId

    是项目artifact唯一的基地址名

    packaging

    artifact打包的方式,如jar、war、ear等等。默认为jar。 这个不仅表示项目最终产生何种后缀的文件,也表示build过程使用什么样的lifecycle。

    version

    artifact的版本,通常能看见为类似0.0.1-SNAPSHOT,其中SNAPSHOT表示项目开发中,为开发版本

    name

    表示项目的展现名,在maven生成的文档中使用

    url

    表示项目的地址,在maven生成的文档中使用

    description

    表示项目的描述,在maven生成的文档中使用

    dependencies

    表示依赖,在子节点dependencies中添加具体依赖的groupId artifactId和version

    build

    表示build配置

    parent

    表示父pom

    groupId:artifactId:version唯一确定了一个artifact

  2. Artifact

    一个项目将要产生的文件,可以是jar文件,源文件,二进制文件,war文件,甚至是pom文件。每个artifact都由groupId:artifactId:version组成的标识符唯一识别。需要被使用(依赖)的artifact都要放在仓库

  3. Repositories

    Repositories是用来存储Artifact的。如果说我们的项目产生的 Artifact是一个个小工具,那么Repositories就是一个仓库,里面有我们自己创建的工具,也可以储存别人造的工具,我们在项目中需要使用 某种工具时,在pom中声明dependency,编译代码时就会根据dependency去下载工具(Artifact),供自己使用。

    对于自己的项目完成后可以通过mvn install命令将项目放到仓库(Repositories)中
    仓库分为本地仓库和远程仓库,远程仓库是指远程服务器上用于存储Artifact的仓库,本地仓库是指本机存储Artifact的仓库,对于windows机器本地仓库地址为系统用户的.m2/repository下面。

    对于需要的依赖,在pom中添加dependency即可,可以在maven的仓库中搜索:http://mvnrepository.com/

  4. Build(Lifecycle -> Phase -> Goal)

    Lifecycle(生 命周期),是指一个项目build的过程。这是maven最高级别的的控制单元,它是一系列的phase组成,也就是说,一个生命周期,就是一个大任务的 总称,不管它里面分成多少个子任务,反正就是运行一个lifecycle,就是交待了一个任务,运行完后,就得到了一个结果,中间的过程,是phase完 成的,自己可以定义自己的lifecycle,包含自己想要的phase

    maven的Build Lifecycle分为三种,分别为default(处理项目的部署)、clean(处理项目的清理)、site(处理项目的文档生成)。他们都包含不同的lifecycle。

    可以理解为任务单元,lifecycle是总任务,phase就是总任务分出来的一个个子任务,但是这些子任务是被规格化的,它可以同时被多个lifecycle所包含, 一个lifecycle可以包含任意个phase,phase的执行是按顺序的,一个phase可以绑定很多个goal,至少为一个,没有goal的 phase是没有意义的

    下面重点介绍default Build Lifecycle几个重要的phase:

    validate

    验证项目是否正确以及必须的信息是否可用

    compile

    编译源代码

    test

    测试编译后的代码,即执行单元测试代码

    package

    打包编译后的代码,在target目录下生成package文件

    integration-test

    处理package以便需要时可以部署到集成测试环境

    verify

    检验package是否有效并且达到质量标准

    install

    安装package到本地仓库,方便本地其它项目使用

    deploy

    部署,拷贝最终的package到远程仓库和替他开发这或项目共享,在集成或发布环境完成

    以上的phase是有序的(注意实际两个相邻phase之间还有其他phase被省略,完整phase见lifecycle),下面一个phase的执行必须在上一个phase完成后

    若直接以某一个phase为goal,将先执行完它之前的phase,如mvn install
    将会先validate -> compile -> test -> package -> integration-test ->verify最后再执行install phase

    goal代表一个特定任务

    A goal represents a specific task (finer than a build phase) 
    which contributes to the building and managing of a project.

    mvn package表示打包的任务,通过上面的介绍我们知道,这个任务的执行会先执行package phase之前的phase

    mvn deploy表示部署的任务

    mven clean install则表示先执行clean的phase(包含其他子phase),再执行install的phase。

    mojo:

    lifecycle与phase与goal都是概念上的东西,mojo才是做具体事情的,
    可以简单理解mojo为goal的实现类,它继承于AbstractMojo,
    有一个execute方法,goal等的定义都是通过在mojo里定义一些
    注释的anotation来实现的,maven会在打包时,自动根据这些anotation
    生成一些xml文件,放在plugin的jar包里
  5. Archetype

    原型对于项目的作用就相当于模具对于工具的作用,我们想做一个锤子,将铁水倒入模具成型后,稍加修改就可以了。

    类似我们可以根据项目类型的需要使用不同的Archetype创建项目。通过Archetype我们可以快速标准的创建项目。利用Archetype创建完项目后都有标准的文件夹目录结构

    既然Archetype相当于模具,那么当然可以自己再造模具了啊,创建Archetype

    下面介绍利用maven自带的集中Archetype创建项目。创建项目的goal为 mvn archetype:generate,并且指定archetypeArtifactId,其中archetypeArtifactId见maven自带 的archetypeArtifactId

  6. Plugin

    maven的核心仅仅定义了抽象的生命周期,具体的任务是交由插件完成的,插件以独立的形式存在。
    对于插件本身,为了能够复用代码,它往往能够完成多个任务。如maven-dependency-plugin有十多个目标,每个目标对应了一个功能,如 dependency:analyze、 dependency:tree和dependency:list。这是一种通用的写法,冒号前面是插件前缀,后面是该插件的目标。

    maven的生命周期与插件相互绑定,用以完成实际的构建任务。具体而言,是生命周期的 阶段与插件的目标相互绑定,已完成某个具体的构建任务。例如项目编译这一任务,它对应了default生命周期的compile阶段,而maven- compiler-plugin这一插件的compile目标能够完成该任务,因此将他们绑定。

    比如maven缺省的三个生命周期: clean, default, site和插件绑定如下:

    Clean

    clean clean:clean

    Site

    site site:site site-deploy site:deploy

    Default

    process-resources resources:resources
    compile compiler:compile
    process-test-resources resources:testResources
    test-compile compiler:testCompile
    test surefire:test package ejb:ejb or ejb3:ejb3 or jar:jar or par:par or rar:rar or war:war
    install install:install
    deploy deploy:deploy

    用户还能够自己选择奖某个插件目标绑定到生命周期的某个阶段以执行更多更特色的任务。

    比如:

    <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <version>2.1</version> <executions> <execution> <id>copy</id> <phase>install</phase> <goals> <goal>copy-dependencies</goal> </goals> <configuration> <outputDirectory>lib</outputDirectory> </configuration> </execution> </executions> </plugin>

    定义了一个id为copy的任务,利用插件maven-dependency-plugin的copy-dependencies目标绑定到default生命周期的install阶段,来实现项目依赖的jar包的自动复制。

    当插件目标被绑定到不同的生命周期阶段时候,其执行顺序会有生命周期阶段的先后顺序决定的。如果多个目标被绑定到同一个阶段,他们的执行顺序是由插件声明的先后顺序决定目标的执行顺序。

  7. profile

    一个优秀的构建系统必须足够灵活,应该能够让项目在不同的环境下都能成功构建。maven为了支持构建的灵活性,内置了三大特性,即:属性、profile和资源过滤。

    profile定义了一系列的profile变量,在具体构建时可用使用其中的某个profile去变量替换资源文件。

Maven设计特点

在上面的介绍里我们花了很长的篇幅来介绍maven的模型,概念,功能,和运作方式。大家也跟了解Maven是基于project这个领域对象模型上,以项目周期管理为目标而构建的领域平台。

  1. 设计了领域模型,所有的功能围绕项目Project这个领域模型构建

  2. 设计了领域模型的生命周期和执行方式(lifecycle-phase-goal)

  3. 设计了项目的原型模式(architype)

  4. 设计了可扩展的插件体系(plugin-mojo)

  5. 设计了依赖管理(dependencies)

  6. 设计了动态配置机制(profile)

  7. 设计了artiface仓库模型(repositories)

从这7个设计点可以看出,maven这个平台设计得很清晰,对需要解决的问题(项目管理构建)设计了一系列的概念, 功能,流程,方便maven的使用者明确的掌握,同时又可以针对自己的个性化需要去定制扩展平台的功能。

构建maven式领域平台

前面我们都是在介绍Maven本身和他的设计特点。 现在我们要发散思考,这种设计在我们用来做自己业务系统的领域平台时有什么可以借鉴。

Maven是基于领域模型驱动设计的平台,围绕这个业务模型,从他的起始状态到结束状态有一个明显的生命周期概念, 在这个生命周期里,不同的功能点独立实现同时又被复用形成多个顺序执行的任务单元推动周期的执行。

在我们的业务系统中也有很多类似的需要。 比如下面我们用招商和交易下单为例。

招商平台和Maven平台类比

  1. 什么是招商

    每年大促前期最重要的准备工作就是招商,招商就是淘宝小二创建了一个活动项目,设计这个 活动的玩法, 然后吸引一些商家带着他们商品参加这个活动,然后小二通过各种资质验证保证报名商家的资质,并通过各种条件在这些商家中选择出最后参加活动的结果。然后这 个项目活动在参与者,玩法等确定下,去执行一些必要的动作,保障这个活动项目在活动期间能够按照设计的完成。

  2. 招商的领域模型(domain)

    招商中最重要的领域模型是活动,我们也可以更规范的成为活动项目(project),每一次小二开始一个招商活动,其实就是设计一个招商活动项目。项目里需要明确项目的参与者,项目的时间(报名期,审核期,活动期),项目的玩法,项目的产出和需要执行的任务。

  3. 活动项目的生命周期(lifecycle)

    很直观,我们就可以确定活动项目是有一个生命周期的。从小二创建活动项目开始到活动结束,基本会经历一下周期,创建->报名->审核->启动->运行->结束->收尾。

    每个周期可以分多个阶段,每个阶段都有多个目标需要被执行。这些任务可以被灵活复用。
    如何设计这些周期,阶段和目标对招商平台化是否成功有决定性作用。

  4. 活动项目的原型模板(architype)

    每次小二设计一个活动项目,从资质,玩法,到运作方式等都需要做很多配置,管理。资深运 营小二如何把他们的经验沉淀起来。避免下次类似的活动项目必须从头开始,新手小二也很难设计出一个成功的活动。这些就需要把这些活动按照一定的模式沉淀成 原型(项目的模板),方便下一次即使是新手也可以快速的构建高效的活动项目。那么招商平台就也需要设计类似maven 原型类似的功能。

  5. 可扩展的插件体系(plugin-mojo)

    招商可以说是根据业务方需求,不停的响应提供新的功能支持新的需求等。当新的需求来的时 候,我们需要分析出平台不足或者需要定制的功能点,然后以插件扩展的方式完成开发,同时能把这些功能很好的注册沉淀到平台,平台的功.能随着业务的发展越 来越强大。比如支持更多的资质校验,支持更多的算法模型,对已有流程如何进行定制扩展,加入新的流程点等等。都需要平台提供一个类maven的可扩展的插 件体系。

  6. 依赖管理(dependencies)

    招商活动会有很多的依赖,比如IC,UIC,报名的商家和商品资源,搜索算法等等。如何把这些依赖类似maven一样管理起来,对招商活动项目的运作和监控也就更加直观。

  7. 动态配置机制(profile)

    很明显,这个机制对招商活动项目也很有用处,比如每次活动对商品的打标,活动时间之类都需要类似的功能机制去保障。方便小二的使用调整。比如小二可以预先准备一些配置,然后根据实际情况,切换不同的配置。

  8. artiface仓库模型(repositories)

    活动项目依赖的各种插件实现, 活动结束后生成的案例资源,都可以以案例库的方式存储起来。方便更进一步的知识积累和业务扩展。

这些只是对招商这个复杂系统的初步想法,具体招商如何设计模型,生命周期等都需要结合目前招商的功能,按照这种思路,我相信我们的招商平台会有一个很好的架构,以后也许我们可以给小二提供类似maven命令的方式来构建活动了,:)

mvn create 创建活动 mvn enroll 报名 mvn review 审核 mvn start 启动 mvn close 结束 mvn clear 扫尾

招商平台化会包括以下功能:

  1. 活动项目对象模型

  2. 活动项目构建引擎

  3. 开放平台

  4. 原型管理

  5. 业务识别

  6. ...

通过这些我们打造一个强大的招商平台。

交易下单平台(Buy)和Maven平台类比

另一个很类似的就是buy下单了,基于订单模型,下单是个典型的生命周期,也很适合用maven的思路来设计。 大家也可以按照类似的思路分析下。 此处省略 1000字,:)。

mvn buy mvn promotion mvn ... mvn order

总结

在工具软件里,有很多很好的设计,这些设计对我们做业务系统是个很好的参考。 比如Eclipse, Maven(还可以关注Gradle,这个设计更好),我们可以用这些平台系统来作为我们平台化的参考类比设计,开拓我们的思路。

文章来自阿里巴巴技术协会(ATA)精选集,原文首发于阿里云栖社区:http://yq.aliyun.com/articles/2916云栖社区是由阿里云负责运营、阿里巴巴技术协会和阿里巴巴集团各技术团队提供内容支持的开放式技术社区http://yq.aliyun.com

本站文章除注明转载外,均为本站原创或编译。欢迎任何形式的转载,但请务必注明出处,尊重他人劳动共创开源社区。
转载请注明:文章转载自 开源中国社区 [http://www.oschina.net]
本文标题:换个视角看 Maven:一个领域平台的优美设计
分享
评论(16)
最新评论
0
目前来讲,我依然喜欢 Maven 更多一些。 Gradle 语法简洁,结合更自由的 Task 功能,但是:
1. 慢,很慢,非常慢。。。慢得无法忍受(同样一个小项目的构建时间是 Maven 4 倍以上)。
2. 就生态圈来讲, Maven 的插件非常得多,很多找不到对应的 Gradle Plugin。
3. Gradlew(Gradle 推荐方式) 运行项目很扯蛋,不知道它的文件ash1码还是其他判断的,在我的 .gradle 目录下,同一版本的 gradle 可以下几次,我真是服了它,光这个目录就占了几G(全部是各版本的 gradle)。
4. 早期的 Gradle 演变太快,语法兼容性很差。
0
楼猪,你在这里大谈特谈Maven的优点,能说一说Maven的缺点吗?
0

引用来自“Brox”的评论

跟我大php的composer比差多了

引用来自“南湖船老大”的评论

不带这么瞎说的。按出场顺序粗略地说,make是ANT它爹,ANT是maven他爹,maven是composer和gradle他爹。maven发展很多年了,composer的普及度和maven完全不在数量级上,在OSC做一个调查,使用composer的少之又少,宏哥肯定没用。而Java的版本管理和依赖普及度远远超过90%。composer使用起来也算简单,但说比maven强就扯淡了。
我瞎掰
0

引用来自“waylau”的评论

上一篇Gradle的教程

https://github.com/waylau/Gradle-2-User-Guide
写的非常好,赞一个
0

引用来自“Brox”的评论

跟我大php的composer比差多了
不带这么瞎说的。按出场顺序粗略地说,make是ANT它爹,ANT是maven他爹,maven是composer和gradle他爹。maven发展很多年了,composer的普及度和maven完全不在数量级上,在OSC做一个调查,使用composer的少之又少,宏哥肯定没用。而Java的版本管理和依赖普及度远远超过90%。composer使用起来也算简单,但说比maven强就扯淡了。
0
作者对软件开发有深刻见地。
0

引用来自“Feng_Yu”的评论

已经用上gradle了,兼容maven和ant,更灵活的构建方式,值得拥有

引用来自“西夏一品堂”的评论

gradle比maven到底好在哪里?

引用来自“水山清风”的评论

一用就知道,你试试用 maven 写个 task?

引用来自“水山清风”的评论

话说还是 sbt 好
+1
0
上一篇Gradle的教程

https://github.com/waylau/Gradle-2-User-Guide
0

引用来自“Feng_Yu”的评论

已经用上gradle了,兼容maven和ant,更灵活的构建方式,值得拥有

引用来自“翟志军”的评论

兼容的意思是?

引用来自“snowdream”的评论

拿过来接着用
这个对我很有启发,ant.importBuild 'build.xml'


谢谢啦。
0

引用来自“Feng_Yu”的评论

已经用上gradle了,兼容maven和ant,更灵活的构建方式,值得拥有

引用来自“翟志军”的评论

兼容的意思是?
拿过来接着用
0

引用来自“Feng_Yu”的评论

已经用上gradle了,兼容maven和ant,更灵活的构建方式,值得拥有
兼容的意思是?
0
跟我大php的composer比差多了
0

引用来自“Feng_Yu”的评论

已经用上gradle了,兼容maven和ant,更灵活的构建方式,值得拥有

引用来自“西夏一品堂”的评论

gradle比maven到底好在哪里?

引用来自“水山清风”的评论

一用就知道,你试试用 maven 写个 task?
话说还是 sbt 好
0

引用来自“Feng_Yu”的评论

已经用上gradle了,兼容maven和ant,更灵活的构建方式,值得拥有

引用来自“西夏一品堂”的评论

gradle比maven到底好在哪里?
一用就知道,你试试用 maven 写个 task?
0

引用来自“Feng_Yu”的评论

已经用上gradle了,兼容maven和ant,更灵活的构建方式,值得拥有
gradle比maven到底好在哪里?
0
已经用上gradle了,兼容maven和ant,更灵活的构建方式,值得拥有
顶部