写点什么

程序员开发大型应用程序的技巧

  • 2012-04-24
  • 本文字数:4245 字

    阅读完需:约 14 分钟

假如你是一名 Java 开发者,正在开发和维护包含 2000 个类并使用了很多框架的应用程序。你要如何理解这些代码呢?在典型的 Java 企业项目小组中,大部分能够帮你的高级工程师看起来都很忙,文档也很少。你需要尽快交付成果,并向项目组证明自己的能力。你会如何处理这种状况呢?这篇文章为开始开发新项目的 Java 开发者提供了一些建议。

1. 不要试图一下子搞懂整个项目

仔细考虑一下,为什么你会想要先理解项目代码呢?大部分情况是有人要求你修复一个 bug,或者增强系统已有功能。你要做的第一件事情不是理解整个项目的架构。当对项目进行维护时,这样做(理解整个项目架构)可能会对你造成巨大的压力。

即便是有 10 年编程经验的 Java 开发者,也无法理解项目的核心工作机制,尽管他们可能已经在这个项目工作超过一年(假设他们并非最初的开发人员)。比如,对于认证机制或事务管理机制还是缺乏确切的认识。

他们是怎么做的呢?他们对于自己负责的部分非常了解,并且能够交付价值给小组。每天的交付价值远比了解一些以后还不确定有没有的东西重要的多。

2. 关注于尽快交付价值

那我是要打消你对于理解项目架构的热情吗?完全不是。我只是要求你尽早地交付价值,一旦你开始一个项目,搭建了开发环境,你就不应该花一两周时间才交付内容,无论它的规模大小如何。假如你是一位有经验的程序员,却两周都没有任何交付,你的经理怎么会知道你是真的在工作,还是在看新闻呢?。

所以交付能够将事情变得简单。不要认为在做有价值的交付前,你必须理解整个项目。这是完全错误的。加一段 javascript 的验证代码对业务就很有价值,经理能够通过你的交付对你更加信任。这样能够向上级领导证明你的贡献以及员工价值。

日复一日,在不断修复 bug 及增强功能之后,你就能够慢慢开始理解项目架构。不要低估对系统方方面面理解时需要花费的时间。花 3 到 4 天理解认证机制,2 到 3 天理解事务管理。这些都是依靠之前的相似项目的经历,但关键还是要花时间才能透彻的理解。要在日常工作中挤出时间,不要向经理要求特定的时间来做这些。

找找项目是否有一些有效维护的单元测试用例。有效的单元测试用例是理解大型项目代码很好的途径。单元测试能够帮助你理解代码片段,包括一个单元的外部接口(单元如何被调用以及返回内容)及其内部实现(调试单元测试比调试整个实际用例简单许多)。

你如果能够很好的理解一些内容,那么就写些笔记,或者画些类图、时序图、数据模型图等,以便你或日后其他的开发者可以进行维护。

3. 维护大型项目所必须的技能

你能从事当前的工作,必然已经具有良好的 java 技术。我们来谈谈能够让你在新项目中良好表现的其他技能。大部分时间里,你在项目中的任务是修复 bug 和增强功能。

有两项很重要的技能能够在你维护大型项目代码起到帮助。

3.1 能够迅速发现需要的类

在任何维护活动中,无论是修复 bug 或增强功能,第一件事情就是识别出当前修复或增强的用例中调用的类。当你定位到需要修复或增强的类 / 方法,就已经完工了一半。

3.2 能够分析变更的影响

当你在完成必要的修改或增强工作后,最重要的就是要确认你的修改没有破坏代码的其他部分。你要用你的 java 技术及对其他框架的理解找出变更可能影响的部分。下面两个简单的例子详细描述了最后提及的情况:

  • 当类 A 的 equals() 方法变更后,调用保存 A 实例的 List 的 contains() 方法时就会受到影响。若 Java 知识不够,就很难考虑到这样的影响。
  • 在 web 项目中,我们假设“user id”保存在 session 中。新加入的程序员可能在“user id”中加入一些信息来修复 bug,但是却不知道那会影响到 与“user id”关联的用例。

因此,既要深入了解 Java 语言,又要深入了解你在应用中使用的框架,这样才能分析出一个改变的影响。

当你提高了如上两个技能,尽管你对项目不是非常了解,但大部分的维护任务会变得简单很多。如果你想要修复一个 bug,就会定位并修复这个 bug,并且保证变更不会破坏项目的其他部分。如果你想要增强或加入特性,基本上你只需要模仿现有的特性,使用类似的设计。

在一个在线银行项目中,为什么“查看账户摘要”和“查看交易历史”的设计要有巨大的差别呢?如果你理解了“查看账户摘要”的设计,完全可以模仿开发出“查看交易历史”的功能。

就修复 bug 和增强来说,你不必完全理解所有 2000 个类的工作内容和代码驱动系统运行的原理。只要有上面的技能,你就能很快定位需要修改的代码,使用良好的 java 和框架技能修复,保证变更不会破坏项目的其他部分,然后交付,尽管你可能只知道一小部分项目的设计。

4. 使用工具找到所需变更内容以及变更产生的影响

继续我们尽快交付的主题,你应该寻找工具作为辅助,只需要对项目又很少理解,就能帮助你尽快实施交付。

4.1 迅速发现所需变更内容的工具

无论是修复 bug 还是增强系统,首先你都要找到该用例调用且需要修改的类及方法。基本上有两种方式理解用例的工作方式,静态代码分析和运行时分析。

源码分析统计会扫描所有代码并且展现类之间的关系。市场上有很多工具。比如:Architexa、AgileJ、UModel、Poseidon 等。

所有静态代码分析工具的缺点在于,它们无法确切展现 用例中类或方法的运行时调用情况。因此 Java 新加入了一些特性,如回调机制(callback patterns)。比方说,静态分析工具无法推断出当前页面提交按钮被点击时,会调用哪个 Servlet。

运行时分析工具能够展现类和方法在用例运行时的状态。这样的工具包括:MaintainJ、Diver、jSonde、Java Call Tracer 等。这些工具可以捕获运行时的堆栈状态,并以此为用例生成序列图和类图。

序列图会展现该用例在运行时所有调用的方法。如果你在修复 bug,那么这个 bug 很可能就是这些被调用的方法之一。

如果你在增强已有功能,可能是新增验证,修改 DAO 等,那么就可以利用序列图理解调用流程然后再修改。

如果你在新增功能,那么就可以找到一些相似的特性,利用序列图理解调用流程,然后模仿开发新功能。

要仔细地挑选运行时分析工具。信息过多是这类工具的主要问题。选择一些工具,能够提供简单的信息,过滤掉无效信息,并能够方便的查看各种视图。

4.2 发现变更产生影响的工具

若单元测试有效,你就可以通过运行单元测试发现变更有没有破坏其他测试用例。有效维护并且覆盖大型企业应用的单元测试还是比较少的。下面有一些针对该情况的工具。

在此,仍然是有两种技术——静态代码分析和运行时分析——可以使用。市场中有很多静态代码分析工具可用。如:Lattix、Structure101、Coverity、nWire 和 IntelliJ’s DSM。

对于变更后的类,上述工具均可识别对该类存在依赖的类的集合。开发者需要根据这些信息“猜测”可能产生影响的用例,因为这些工具无法展示运行时类之间的调用关系。

市场上可以用于运行时影响分析的工具并不多,可能只有 MaintainJ。MaintainJ 先会捕获在用例中调用的所有类和方法。当所有用例的上述信息都被捕获之后,就很容易发现类的变更对用例的影响。MaintainJ 能够有效工作的前提条件就是项目的所有用例都应当先运行一遍,以便能够获得运行时的依赖关系。

总之,目前你在迅速准确分析变更影响方面,还是可以从工具中获得有限的帮助。首先根据需要实施一些影响分析,然后根据自己或小组其他高级成员评审来判断变更的影响。你可能需要使用上述工具对你的判断进行反复确认。

5. 对上述内容的两个忠告

5.1 不要降低代码质量

为了快速交付,可以不全盘理解架构,但绝不能以降低代码质量为条件。下面是一些你可能因为只考虑快速交付而引发的代码质量问题。

因为修改代码涉及到很多的依赖关系,所以新增代码相对而言风险较小。例如,有五个用例都调用了某个方法。为了改进某个用例,你需要修改这个方法的实现。最简单的做法就是复制这个方法,重命名,然后在改进的用例中调用新方法。千万不要这么做。代码冗余绝对是非常有害的。你要尝试对方法进行包装或者重写,甚至是直接修改,然后重新测试所有用例,通常停下来想一想,然后亲手去实施,是一种不错的方式。

另一个例子是将“private”方法改为“public”,让别的类也可以调用。尽量不要将非必须的部分暴露出来。假如是为了更好的设计而需要重构,那么就应当着手去做。

大部分应用都有确定的结构和模式来实施。修复或增强程序时,你要确保不会偏离这样的模式。如果对规约不确定,那么就请其他高级开发者来审核你的变更。如果你必须做一些违背规约的动作,那么就尽量放置于规模较小的类中(一个 200 行代码的类中的私有函数应当不会影响应用的整体设计)

5.2 不要停止深入理解项目架构

按照文章列出的方式,假设你能够在对项目了解较少的情况下进行交付,并持续这样下去,可能就会停止对项目架构的深入了解。这从长远角度来说对你的职业生涯没有帮助。当你的经验增加时,就会承担比较大的模块任务。如构建一个完整的新特性,或者修改项目的一些基础设计等较大的改进。当能够做这些改进时,你对项目的整体架构应该相当了解。文中列举的方法只是让你在最短的时间内提升自己,而不是阻止你完整理解整个项目。

6. 结论

整篇文章的重点在于,对项目进行必要了解,然后进行快速交付。你可以在不降低代码质量的前提下做到这一点。

如果要修复 bug,那么迅速定位并修复。可以在必要的时候使用运行时分析工具。如果要新增特性,那么就可以寻找类似特性,理解流程(在必要的时候使用工具)并编写。

或许这些听起来很简单,但是实用吗?当然。前提是你有良好的 java 技术,以及对框架足够了解,然后才能先修改代码,再分析变更所产生的影响。分析变更所产生的影响比实施变需要更多技巧。你可能需要高级开发人员协助你分析变更影响。

大约有 50% 的 IT 可操作预算用于简单的 bug 修复和功能增强。文中的建议对于在维护活动中节省经费应当还是很有帮助的。

作者 Choudary Kothapalli 也是 MaintainJ 项目的创立者。

关于作者

Choudary Kothapalli MaintainJ Inc. 创始人。该公司提供的工具用于在维护大型 Java 项目时节省开支。作者在开发和维护企业级 Java 应用方面已经有 15 年的经验,并且具有 Sun 认证的企业架构师与 Java 开发者资格。他目前和妻子以及 2 个儿子居住在加拿大多伦多。

关于译者

陈晨, 长期从事互联网信息收集分析领域架构研究。对海量数据处理,NoSQL 等处理运用有丰富经验,关注过程方法及其自动化。他的新浪微博:一酌散千忧


感谢侯伯薇对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ )或者腾讯微博( @InfoQ )关注我们,并与我们的编辑和其他读者朋友交流。

2012-04-24 00:0011325

评论

发布
暂无评论
发现更多内容

手机摄像头越多拍照效果越好吗?

InfoQ IT百科

射频芯片在手机上起到什么作用?

InfoQ IT百科

C语言的三子棋,用22天总结了一份完美的SQL学习笔记

爱好编程进阶

Java 面试 后端开发

CPU和GPU有什么区别?

InfoQ IT百科

前三个月免费试用!博睿数据告警平台OneAlert火热大促进行中

博睿数据

日志脱敏是什么意思?为什么要做日志脱敏?

行云管家

数据安全 日志脱敏

70道Java开发面试题及答案,2022最新大厂高频微服务面试总结

爱好编程进阶

Java 面试 后端开发

Kafka生成消息时的3种分区策略

华为云开发者联盟

kafka 分区 Default Partitioner 分区策略 Partitioner

ActiveMQ消息存储持久化,华为java面试难度

爱好编程进阶

Java 面试 后端开发

netty系列之:netty中常用的xml编码解码器

程序那些事

Java Netty 程序那些事 4月月更

如何看待现阶段国内手机操作系统的竞争格局?

InfoQ IT百科

Android系统和iOS系统两大系统占据了手机操作系统98%的市场份额,国产手机操作系统还应该从哪些方面努力才能实现逆袭?

InfoQ IT百科

最近几年,OPPO 、小米等手机厂商都开始走自研芯片之路,这条路能跑通吗?

InfoQ IT百科

手机刷新率越高越好吗?

InfoQ IT百科

有研究显示,现在年轻人越来越不愿意换手机了。下一代智能手机在硬件上出现哪些更新,才会让你有换机的冲动?

InfoQ IT百科

自动化测试的生命周期是什么?

禅道项目管理

自动化测试 生命周期

2019年华为鸿蒙加入手机系统阵营,如何看待鸿蒙这三年的发展?

InfoQ IT百科

虎符交易所Hoo研究院|币海寻珠——四月上半月区块链投融事件Top20

区块链前沿News

区块链 投资 虎符研究院

2020年java岗合集面试复盘,凭借这些文档掌握80%就去进阿里,大牛自我总结500页“Java成长笔记”

爱好编程进阶

Java 面试 后端开发

友好型公链Neo,助力开发者轻松掌握区块链智能合约

TinTinLand

区块链

手机摄像头芯片主要有哪些?

InfoQ IT百科

从构建到治理,业内首本微服务治理技术白皮书正式发布(含免费下载链接)

阿里巴巴云原生

2021金三银四跳槽必备:阿里Java岗面试突击笔记终开源!,springmvc实战视频

爱好编程进阶

Java 面试 后端开发

CRM系统改善客户体验的方法

低代码小观

CRM CRM系统 客户关系管理系统 客户体验 客户体验管理

购买不同品牌的手机,怎么对比硬件配置?

InfoQ IT百科

OPLG:新一代云原生可观测最佳实践

阿里巴巴云原生

银行为什么要上堡垒机?选择哪家好?有案例吗?

行云管家

运维 网络安全 银行 堡垒机

星环科技平滑迁移方案加速国产化替代,助力大数据基础软件自主可控

星环科技

手机运存与内存有什么区别?

InfoQ IT百科

摆脱 AI 生产“小作坊”:如何基于 Kubernetes 构建云原生 AI 平台

阿里巴巴云原生

【Zeekr_Tech】ROS/ROS 2介绍

Zeekr_Tech

操作系统 机器人

程序员开发大型应用程序的技巧_Java_Choudary Kothapalli_InfoQ精选文章