说到软件项目的依赖管理,可以从三个方面来考虑:

一、由build system控制的dependency

现在的build system,都支持一定程度上的dependency management, 比如make支持target之间的dependency,ant也支持其每个target之间的dependency(区别是make的每个非PHONY的target是个文件,make会检查输入与输出之间的timestamp来达到incremental build的效果,而ant则是对上一次build没有任何记忆,除了javac task支持incremental compile)

上面的dependency讲的主要是如何确定build的顺序,但dependency管理的另一个非常重要的目标,是自动获取dependency,并设置好:

  • 对于C++来讲:includedir(-I), libdir(-L)
  • 对于Java来讲:classpath

手工的维护这些path,非常麻烦而且容易出错,因为我们在一个过低的level管理这些信息 - 事实上,正确的做法应该是:用户只需声明我依赖这个component或者我依赖这个library,dependency manager自动帮我设置好这些path。

总的来讲,dependency manager有这么几个作用:

  • 让用户在合适的逻辑层次声明dependency,自动设置好需要的path
  • Resolve transitive dependency
  • Conflict manage (diamond dependency)

这些功能都不是手工能够解决的。

二、不由build system控制的dependency

如果有两个或者多个不同的project,由不同的team开发,甚至使用了不同的build system,那么基本上是不可能把他们放在同一个build pipeline中编译的。但是他们之间又有dependency,该怎么处理?

这里其实就是一个升级的问题, 比如:

B -> A/1.0

而A还是不断的开发,可能会改变已有的实现(引起B的运行时错误),也可能改变已有的接口(引起B的编译时错误),如果B在一段时间之后升级到A的新版本A/1.1,B可能需要很长时间做migration - 或者说integration。其实从continuous integration的角度来理解这个问题,正确的做法应该是:

A要尽可能快的推出一个新的release,而B要立马跟上,这样每次B的改动都非常小,不容易出错,出了错也容易解决。

但推出一个新的release毕竟不是件小事,很多team会有自己的担心:资源不够,risk太高等等 - 所以上述是一个比较理想的情况。在达到那个情况之前,可以另外有个方案:

B继续使用A/1.0, 但是同时B新开出一个branch:B/edge,依赖于最新的A的代码,A的每次build,都会trigger B/edge的build (edge build),这样保证B总是build against最新的A,任何问题都可以在第一时间发现,并fix

关于edge build,值得另外写一篇文章讨论一下。

这里,这种不由build system控制的dependency,就需要由其他系统来控制,比如各种CI server中的job,一个job会trigger另外一个job,也是一种dependency关系,刚好对应起来。

三、dependency graph的显示

软件项目之间的dependency graph,很好的反映了各个项目之间的关系,注意这个dependency的单位不是project,而是release,这更动态的反映出了依赖关系,同时,由于你知道每个项目的dependency,根据这个信息就能建出一张完整的dependency graph,从而能得出所有consumer的信息,于是,我就有了关于这个项目的所有dependency和consumer的信息:

  • 我用了那些项目,用的版本会不会太老?
  • 我被哪些项目用了?受不受欢迎?是不是可以停止支持某个release了(如果没有太多consumer的话)

显示一个项目的dependency时,可以有以下几部分:

  • 直接dependency
  • 间接dependency
  • 直接consumer
  • 间接consumer
  • dependency graph

关于dependency graph,要注意的是:首先它是一张完整的图,正确的显示了所有直接dependency和间接dependency,但是这样的图,对于一个大的项目来讲的话,会比较乱 - 考虑某个项目即是直接dependency,又是间接dependency的情况,就会有多个箭头指向它。所以一般显示的时候,会将其的transitive reduction显示出来(tred,dot自动做reduction),在保证其reachbility的同时,减少边的数量,使图看起来比较简练:

还有要注意的一点是,我们需要提供额外的metadata,来保证这个图的正确性。以ivy为列,ivy.xml提供了比较完整的dependency信息(没有类似机制的build system至少要产生这种metadata),但其问题是对于有dependency conflict的情况(diamond dependency),如上面第二张图,如果b和c依赖于不同版本的d,单凭ivy.xml无法确认到底选d的那个版本,这是ant/ivy在build过程当时选择一定的conflict manager方式确定下来的,而这个信息,必须以某种方式告诉dependency graph - 一般的方式就是在build过程中产生metadata并予以保存。

对于没有ivy.xml这种机制的build system,需要产生metadata一保存:

  • 所有直接的dependency
  • 有conflict的间接dependency

然后可以根据所有项目的这个信息产生正确的dependency graph

谈谈软件项目的dependency的更多相关文章

  1. 学习笔记——Maven实战(三)多模块项目的POM重构

    重复,还是重复 程序员应该有狗一般的嗅觉,要能嗅到重复这一最常见的坏味道,不管重复披着怎样的外衣,一旦发现,都应该毫不留情地彻底地将其干掉.不要因为POM不是产品代码而纵容重复在这里发酵,例如这样一段 ...

  2. 团队项目——编写项目的Spec

    团队项目--编写项目的Spec 一.Spec的目标        spec主要用来说明软件的外部功能,和用户的交互情况,主要用来说明软件内部的设计.图片编辑器是与生活息息相关的一个必备软件,随的流行, ...

  3. 为什么项目的jar包会和tomcat的jar包冲突?

    为什么项目的jar包会和tomcat的jar包冲突? 碰到这个问题,猜测tomcat启动时会将自己的lib和项目的lib在逻辑上归并为一个大的lib,但是并没有做版本区分以及去重,这样相同的包可能就有 ...

  4. IDEA Maven项目的Mybatis逆向工程

    IDEA Maven项目的Mybatis逆向工程 1.配置.pom 如果是在多模块开发下,该文件逆向工程要生成的那个模块下的pom文件. <build> <plugins> & ...

  5. eclipse 导入包含子maven项目的maven项目时的正确方式(父子项目)

    eclipse 导入包含子maven项目的maven项目时的正确方式(父子项目) NO1 导入时依次选择 import > Maven > Existing Maven Projects ...

  6. dajie项目的坑

    1.首先IDEA巨坑无比的地方是引入时,只要哪怕一个依赖下载不到,就会长期阻塞,删除.重新引入都没用!! 2.注释掉项目及其子项目中所有pom.xml中引用的spring仓库,否则即使maven配置阿 ...

  7. mavean项目的jar位置的影响

    由于项目的数据库需求改变了,有mysql数据库变为oracle的,那么对于项目就是需要改变数据库连接池.这个项目运用了mavean框架,那么下载jar在pom.xml文件中填写就可以了,但是oracl ...

  8. Spring Boot 不使用默认的 parent,改用自己的项目的 parent

    在初学spring boot时,官方示例中,都是让我们继承一个spring的 spring-boot-starter-parent 这个parent: <parent> <group ...

  9. 对于maven创建spark项目的pom.xml配置文件(图文详解)

    不多说,直接上干货! http://mvnrepository.com/ 这里,怎么创建,见 Spark编程环境搭建(基于Intellij IDEA的Ultimate版本)(包含Java和Scala版 ...

随机推荐

  1. CSS3 rgba

    复制粘贴: <!DOCTYPE html > <html > <head> <meta charset="utf-8"> <t ...

  2. yii2 输出xml格式数据

    作者:白狼 出处:http://www.manks.top/yii2_xml_response.html.html本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文 ...

  3. Centos中jdk的环境配置

    在Centos中,进行配置jdk的环境,这个还是折腾了我听挺久的.特别是,在一次配置中,导致后来我的root用户无法登录,并且用其他普通用户登录,使用su - root切换到root用户,都无法使用l ...

  4. Apache安装问题:configure: error: APR not found . Please read the documentation

    Linux上安装Apache时,编译出现错误: checking for APR... no configure: error: APR not found .  Please read the do ...

  5. Jade模板引擎(一)之Attributes

    目录: Attributes Boolean Attributes Style Attributes Class Attributes &Attributes Attributes jade中 ...

  6. sed入门详解教程

    sed是一个比较古老的,功能十分强大的用于文本处理的流编辑器,加上正则表达式的支持,可以进行大量的复杂的文本编辑操作.sed本身是一个非常复杂的工具,有专门的书籍讲解sed的具体用法,但是个人觉得没有 ...

  7. android 利用Path.cubicTo 画 贝塞尔曲线

    Path.cubicTo void android.graphics.Path.cubicTo(float x1, float y1, float x2, float y2, float x3, fl ...

  8. centos6.5编译安装lamp开发环境

    一.系统以及软件的准备 系统及编译安装包的下载地址:http://pan.baidu.com/s/1jIjqinc   密码:ghc2 说明:由于centos6.5是分卷压缩的,且压缩为三个压缩包,所 ...

  9. [书目20160526]Brain Rules 让大脑自由:释放天赋的12条定律

    推荐序1 12条定律,让大脑更聪明推荐序2 走过迷雾地带前  言 人人都有一个不可思议的大脑 定律1:越运动,大脑越聪明 信不信,“驴友”比“沙发土豆”更聪明! 老板,请把办公室的咖啡机换成跑步机! ...

  10. 用PS设计等高线效果的背景图片

    有些简单的单网页,如果利用等高线效果的背景图片,再配合合适的背景色,能达到绚丽的效果.如下图所示: 本文就介绍该等高线效果的背景图片是如何制作的.Follow Me!!!! 1.新建文档,尺寸:100 ...