[Android Pro] 组件化:企业级大型项目必经之路
cp : https://www.csdn.net/article/2011-02-11/291667
摘要:超过一年以上、活跃开发的项目往往到后期陷入了一些共性的问题: 构建速度慢,往往生成一次最终输出产物需要一小时以上; 架构复杂:虽然说架构本身可以用类似于MVC/Service Bus之类的通用
超过一年以上、活跃开发的项目往往到后期陷入了一些共性的问题:
构建速度慢,往往生成一次最终输出产物需要一小时以上;
架构复杂:虽然说架构本身可以用类似于MVC/Service Bus之类的通用进行描述,但实际上使架构变得复杂的往往是业务本身;
开发速度慢,构建速度是因素之一,它使得持续集成的反馈大大低于预期;然而这类大的项目往往被通过各种技术手段进行了分层、分project的切割,你要面对的可能不是一个project,而是一组项目群。我之前参与过、咨询过的项目里,开发人员打开IDE要面对的project少则几十个,多则上百个。即便以目前最强劲的开发机器,面对这动辄几十万上百万行的代码,依然显得力不从心。
以及由上面而引来的一系列问题:例如新人培养,知识传递等等。
在提出这些问题的解决方案之前,我们看看这些问题是如何产生的。通常需要很长时间这些问题才成为问题,而且往往在一开始出现的时候,总有一些快速而有效的解决方案去掩盖,进而加剧了问题的升级,最终成为一个旷日持久需要大量人力才能解决的问题。
项目的产生
新的项目来了。团队成员兴奋的引入了最新的MVC技术框架(比如SpringMVC/ASP.NET MVC)、持久框架、依赖注入框架等等。现在流行的迭代开发方法也被引入。于是前几个迭代过去了,Domain、Service、Web等,分层良好的应用产生了。需求也快速的实现了。代码非常健康。构建速度非常快。所有人都很高兴。
2个月过去了。有心的团队成员不断的重构着代码,确保重复的逻辑、重复的代码被消除。新的人加入了团队。新的业务需求也来了。这些不断重构的代码进一步被不断重构着:终于引发了一些问题:由于只有一条主线:Domain -> DAO -> Service -> Web, 在并行开发下(比如同时有5-8个并行工作)那么公共使用的那条线会不断的产生代码合并冲突/或者业务逻辑冲突。
这不算一个多严重的问题。然而这个问题却制约了团队的规模扩张。比如需要更多的人加入这个项目的时候,耗费在沟通上的时间会大大增加,新加入的成员有效生产力也难以得到提升。
并不算太难解决的的问题。现在团队还不大。团队的架构角色只需要花上一个周末的时间,将现有的代码按照业务逻辑进行纵向切分,划分为不同的小项目,问题算是基本解决。
问题来了
更多的代码被提交。构建速度从2分钟上升到6分钟的时候有人抱怨了一下,于是花点时间优化了构建脚本,时间减少到5分钟。代码继续增长——这是不可避免的趋势——构建时间继续加长,从5分钟上升到11分钟的时候,大家的工作习惯开始发生了一些变化:一旦开始构建,就开始跟旁边的伙伴聊聊天,或者趁这机会喝点咖啡。本地提交在这个时候与持续集成服务器有点不同——本地可能只运行少量的构建步骤、必要的测试,服务器则运行所有的。
从11分钟上升到23分钟的时候,大家觉得要做点什么了。升级了所有开发人员的开发机器,最新的四核8G内存的机器,酷毙了。分布式构建集群也被引入。原来需要23分钟,现在通过分布式之后时间回落到10分钟以内了。
更多的问题
需求在不断的扩张着。代码的规模随之膨胀着。构建时间不引人注意的增长着。直到几年后的一天,突然发现:
1. 即便已经使用分布式,构建需要一个小时
2. 打开IDE面对的是72个项目
3. 虽然能忍,但干什么都有点慢
4. 架构呢?架构呢?
解决思路
大多数解决这类问题的思路仍然停留在表象层面:加机器(改善构建速度)、增强结对编程(改善交流)、写更多的Wiki(增加对代码的共识)。然而却逐渐忽略了一个事实,那就是:
这么庞大的“业务需求”,根本不是一个项目能够承载的。
让我们从代码层面开始。
一个大型项目需要在IDE里面打开数十个project. 这些project之间有着千丝万缕的联系——无论依赖被管理的多么好,没有人能够很清楚的知道他们之间如何被依赖的。更重要的是——大多数时间你都不会碰60%以上的project以及80%的代码。那么这些代码存在的意义何在?
因为你处在一个团队中,别人会用。
于是引用就成了依赖最强、最脆弱的代码引用。
那么,如果我们将这些项目的引用变成二进制引用呢(如JAR, DLL)?由于依赖的这些项目已经经过构建,那么编译的时间可以减少。你也只需要关注自己的项目。
听起来似乎太轻巧了。的确如此。如何获得这些二进制引用?对于JAR而言,假设一个Maven依赖仓库是必须的;对于DLL似乎没有太成熟的方案但总不是太难的问题。
这个过程之中有非常多的实现细节,很可能大多数团队在第一步:分析project依赖就跘住了脚。这么多的project想要拆开是很有挑战的事情,在业务需求的并行压力下,缺乏勇气的团队很可能止步于此。
这些依赖是组件吗?
在进行二进制引用的进程中,你应该不断的问自己这个问题:这个依赖是组件吗?还是只是一个简单的压缩包?
评估一个project是否为一个组件,在我看来有几个约束条件:
1. 是否有超过2个project依赖于它?注意,这里的依赖,不是IDE里面你指定的依赖,而是真实的、API调用的依赖。对于组件化意识不好的团队,这类项目往往成为临时代码堆放地,需要通过识别、迁移,才能将真正有用的组件提取出来。
2. 是否稳定?所谓稳定是指,在过去一段时间内(比如一个月),这个模块没有经过大的调整,API基本稳定,未来的变化只在于增加API的数量而非调整API的架构。
3. 自己依赖于外面的足够少。
通过这一步,往往你可以识别出项目中用到的公共组件、公共API等等。将他们组件化,通过Maven或者自己的依赖库管理起来,标记上版本,然后所有人使用二进制引用。通过这一步,构建时间应当大幅度减少。通过这一过程的梳理,哪些是核心业务逻辑、哪些是可以独立考虑的第三方辅助库,应当可以有一个更为清晰的理解。更重要的是,这些组件可以独立开发、升级、优化,丝毫不会影响到主线的开发过程。
组件是库(Library)还是服务(Service)?
经过上面一步,可能项目中仍然存在一些项目依赖,这些项目往往是公共的,通过API调用的。例如,在某一个银行业务中,支付模块被很多其他业务依赖。支付模块有很多代码,也需要在主进程中与其他模块一起被部署。但支付模块实在是太独立了,虽然与其他的domain之间存在一些类上的简单交互。
采用上面步骤的方法不太合适,原因之一就是它是运行时才有效的依赖——它整体上是一个服务,而非一个静态的库。这个时候你可以考虑将其彻底独立,成为一个独立的service。它的形态可以是一个操作系统服务,或者独立部署的应用。然后写一组标准的轻量级API如REST/WebService来对其进行交互。这样这部分也独立出去了。
重要的考虑
上面看起来轻巧的过程实际上在操作过程中需要耗费很长很长很长的时间。原因之一是组件很难识别。然而难以识别的原因并非是这个过程很难,而在于我们在完成一个项目的过程中倾向于将所有的东西放到一起,顶多通过project区分但仍然缺乏真正物理意义上的隔离。这是一个认知上的障碍,特别是我们面对的是“项目”而不是“产品”。“项目”这个词本身就透露着短期的、目的性强的意义。识别出来的组件本身短期并不会给团队带来多大的好处,反而会增加工作量。就像所有的知识积累工作一样,它们的好处与他们的投入在因果关系上并不连续。
我们得到了什么?
这并非一个理想化的描述,最终我们得到的是:
1. 真正物理隔绝的一组项目群:能够独立构建、开发部署和升级
2. 依赖仓库
3. 分工明确的组件和服务
4. 针对产品的版本和部署策略
原文链接:http://michael.nona.name/archives/359
[Android Pro] 组件化:企业级大型项目必经之路相关推荐
- android组件化架构 书,Android MVVM组件化架构方案
MVVMHabitComponent 关于Android的组件化,相信大家并不陌生,网上谈论组件化的文章,多如过江之鲫,然而一篇基于MVVM模式的组件化方案却很少.结合自身的调研和探索,在此分享一篇基 ...
- XCoreRedux框架:Android UI组件化与Redux实践
XCoreRedux框架:Android UI组件化与Redux实践 @author: 莫川 https://github.com/nuptboyzhb/ XCoreRedux源码+Demo:http ...
- android pod 组件化_使用 Pod 实现私有模块化管理(组件化 Pods 实现方案)
概况 众所周知组件化是个好东西,它把项目拆分成多个模块,让每个模块能够独立出来解除各个模块之间的耦合性,作为每个独立的模块不仅仅能够使用组合的方式去组建各个不同的功能组合(前提是各个组件划分的颗粒度只 ...
- android scheme 配置多个,Android业务组件化之URL Scheme使用
Android业务组件化之URL Scheme使用 H5打包的apk使用(Android平台通过UrlSchemes与第三方应用相互调用) 什么是 URL Scheme? android中的schem ...
- Android之组件化开发
转载请标明出处:[顾林海的博客] 个人开发的微信小程序,目前功能是书籍推荐,后续会完善一些新功能,希望大家多多支持! ##前言 在以前的项目中都是建一个基础库,项目依赖基础库,主项目中集成了所有的功能 ...
- Android进阶——组件化开发实践(一)
一.组件化的意义 随着Android 项目代码和结构逐渐复杂,维护成本会指数型上升,通常我们会利用Android Studio自带的Module去拆分项目代码.但这种拆分显然需要基于一定逻辑和结构,目 ...
- [Android] Git组件化部署
大家好,我系苍王. 以下是我这个系列的相关文章,有兴趣可以参考一下,可以给个喜欢或者关注我的文章. [Android]如何做一个崩溃率少于千分之三噶应用app--章节列表 这一节的内容是Git的组件化 ...
- android app.build文件_网易友品 Android 客户端组件化演进
原文作者:简书 - 四单老师 项目背景 主站业务经历了长期的迭代维护,业务的增长同时带来每个版本业务量繁重,迭代周期很快.同时团队也在不断的扩张,对应拆分了组内不同的业务线对接不同业务线的需求,最初的 ...
- android 蘑菇街组件化,蘑菇街 App 的组件化之路
编辑推荐: 本文来自于csdn,文章主要分享了casatwy 的一些思路和思考问题的角度,希望对您的学习有帮助. 统一的调用实现 将「URL 调用」和「组件间调用」通过 runtime 达到统一,通过 ...
- 一个 Android MVVM 组件化架构框架
模块 app: app壳 工程,是依赖所有组件的壳,该模块不应该包含任何代码,它只作为一个空壳存在,由于项目中使用了EventBusAPT技术,需要索引到各业务组件的对应的APT生成类,所以在 app ...
最新文章
- MED-V服务器部署,MED-V服务器系列之一
- python希尔排序的优缺点_Pythonの希尔排序
- [NewLife.XCode]高级增删改
- C#趣味程序---真分数序列
- ArcGIS将CAD等高线转换为TIN/DEM数据
- 第十九节:终于,JavaScript也有了类(class)的概念
- led伏安特性实验误差分析_高中物理 | 电学实验满分知识点总结+拓展+例题精讲,罕见的好资料,收藏不亏!...
- wampserver 调试 php,phpstrom+wampserver+xdebug配置
- IOS第12天(3,UIViewController的生命周期)
- 100台服务器分发文件,通过简单shell脚本+rsync实现单一文件分发到多台服务器
- 读博总结的总结:读博的那些事儿
- word打开老是配置进度_打开word2010总是出现配置进度怎么办_打开word2010出现配置进度的解决方法-系统城...
- 阿朱说:咨询的历史(万字深度长文)
- 推荐系统的冷启动与效果评估
- Windows下软件提示“没有注册类”问题解决
- 用matlab画散点图并用光滑曲线连接(样条插值)
- Redis——5种数据结构底层实现原理
- 讲述下我在EBC金融外汇平台交易的真实体验
- 基于人工智能视觉芯的高速公路交通事故预警预测方案
- 数据工程师该如何增加核心竞争力?
热门文章
- 四数之和 leetcode
- 420.强密码检测器
- php网站推送消息到公众号,公众号php推送消息
- java对象值传递和对象传递的总结
- Python搜索路径
- 【洛谷 P3384】树链剖分【详解树链剖分】
- adc分辨率和精度的区别_STM32学习笔记—ADC采集数据常见问题
- 对于xfire动态调用webservice接口
- 华东交通大学计算机科学与技术专业,华东交通大学计算机科学与技术专业2016年在湖北理科高考录取最低分数线...
- 用php远程获取MySQL到本地,mysql本地从远程数据库导数据_MySQL