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

一、由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. php 操作mysql 分表的一种方法

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAARUAAAHXCAIAAAAdrFkKAAAgAElEQVR4nOyd61sTx9//+4fcj+6H95

  2. ofbiz 本地化及邮件设置126邮箱

    ofibz登陆功能有通过电子邮件找会密码的功能,但找回密码功能需要配置一个发送email的邮箱账号和smtp服务器的配置,具体配置如下: 1:在ofbiz数据库的表product_store_emai ...

  3. 用MsmqBinding投送message出现的一个灵异事件 【第二篇】

    一直都在用Msmqbinding,也一直忽视了message里面的内容格式是什么样的,这也是微软给我们高层封装带给我们的开发效率,但同时一旦中间出了什么问题, 就不知道从何查起了.有个需求是这样的,服 ...

  4. SQL Server 2000:提示“未与信任SQL SERVER连接相关连”错误

    在使用“用户模式”登陆SQL Server 2000时提示“未与信任SQL SERVER连接相关连”错误,因为在安装SQL Server时选择“仅Windows”模式,所以所有用户都不可以登陆. 解决 ...

  5. 创建一个三角形类,成员变量三边,方法求周长,创建类主类A来测试它

    package com.hanqi.test; public class sanjiaoxing { private double a; private double b; private doubl ...

  6. Linux 性能优化工具 perf top

    1. perf perf 是一个调查 Linux 中各种性能问题的有力工具. NAME perf - Performance analysis tools for Linux SYNOPSIS per ...

  7. Confluent介绍(二)--confluent platform quickstart

    下载 http://www.confluent.io/download,打开后,显示最新版本3.0.0,然后在右边填写信息后,点击Download下载. 之后跳转到下载页面,选择zip 或者 tar都 ...

  8. 烂泥:SQL Server 2005数据库安装

    本文由秀依林枫提供友情赞助,首发于烂泥行天下. 为了能更好的利用服务器,所以打算把该业务进行迁移.因为该业务比较特殊,需要服务器上有相应的硬件支持,所以打算直接升级该服务器目前的操作系统.目前公司服务 ...

  9. 安装DELL R430服务器的过程记录

    序: 本次需要安装一个ineedle设备给客户用,貌似客户是华三.这次领导比较重视,下血本买了一台DELL服务器,似乎花费了1万多大洋.当然配置是比较高了,CPU:Intel(R) Xeon(R) C ...

  10. Android 解读.apk解压后文件详细说明

    转自:http://xdang.org/post-602.html 以下原文: 反编译 — 在apk文件中能得到什么 最近在做android客户端与服务器安全通信,有一种常见的不安全因素:很多软件常常 ...