敏捷、分布式、ALM过程自动化、企业应用架构
posts - 14, comments - 0, trackbacks - 0, articles - 1
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

Tips to Developers Starting on Large Applications

原文引用:http://www.infoq.com/articles/tips-to-developers-starting-on-large-apps

 

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

 

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

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

即便是有着10年可靠编程经验的Java开发者可能也没有理解项目的核心工作机制,尽管他们可能已经在这个项目工作超过一年(假设他们并非原始开发人员)。比如,对于认证机制或事务管理机制。

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

2         关注于尽快交付价值

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

所以交付可以使大家都轻松起来。不要认为你能够做有价值的交付前必须理解整个项目。这是完全错误的。加一段javascript的验证代码对业务就很有价值,经理能够通过你的交付达到对你的信任。这样能够向上级领导证明你的贡献以及员工价值。

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

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

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

 

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

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

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

3.1         能够迅速发现需要的类

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

3.2         能够分析变更的影响

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

a)当类A的equals()方法变更后,调用一个保护A实例的List的contains()方法时就会被影响到。若Java知识不够,很难考虑到这样的影响。

b)在一个web项目中,我们假设“user id”保存在session中。一个新入程序员可能在“user id”中加入一些信息作为bug修复的方法,但是却不知道会影响到那些关联“user id”的用例。

当你提高了如上两个技能,尽管你对项目不是非常了解,但大部分的维护任务会变得简单很多。若你修复一个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 and IntelliJ's DSM。

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

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

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

5         对上述内容的两个忠告

5.1         不要降低代码质量

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

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

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

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

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

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

6         结论

整篇文章集中在对项目进行必要了解的前提下进行快速交付。你可以在不降低代码质量的前提下这么做。

若修复一个bug,迅速定位并修复。有必要可以使用运行时分析工具。若新增一个特写,可以寻找相似特写,理解流程(有必要使用工具)并编写。

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

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

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

About the Author

Choudary Kothapalli is the founder of MaintainJ Inc., the company that builds tools to reduce the costs of maintaining large Java applications. He has over 15 years of experience in developing and maintaining enterprise Java applications. He is a Sun Certified Enterprise Architect and Java Programmer. He lives with his wife and two sons in Toronto, Canada.

 

posted @ 2012-03-29 22:44 一酌散千忧 阅读(409) | 评论 (0)编辑 收藏

软件企业的技术体系架构包括对软件产品本身及生产过程、软件生产环境及生产者的管理和支持,此架构应当基于下列五项基础建设之上:

l 开发技术架构

l 开发环境架构

l 过程管理架构

l 企业产品架构

l 企业人件架构

下面详细介绍各项架构的内容及特点。

 

 

开发技术架构

开发技术架构作为一个软件企业的基石,包括可复用的架构组件、公用的基础代码库等。开发技术框架应当在一个良好的过程管理之下,严格的质量管理与实用性检查,并且鼓励普通技术人员的参与。

1.建立技术架构仓库标准体系与维护模式。建议使用MAVEN作为所有开发技术(包括架构预研与实际项目开发)的基础项目管理工具,实施严格的质量管理和持续集成。

2.选拔组建高素质的架构师队伍,并且鼓励技术人员参与到技术架构仓库的构建和维护。

3.加强技术架构实用性与适用性的检查与改造。

4.架构运营模式的考察,技术架构的改进与预研。技术架构的预研模式比较复杂,多个部门中多个项目可能都会要求进行多个同类框架的考察、比较、环境搭建等工作,若集中在独立架构组可能压力较大。可以考虑架构组内部划分为多个技术领域,如企业基础应用架构、消息中间件、动态化组件、分布式集群等。以技术部门的实施领域作为导向,进行技术架构的预研。

5.开放知识系统的构建(内部wiki,个人博客,视频分享)

根据企业行业背景,需要关注的技术领域包括:企业应用、ESB/SOA、大型分布式架构(在线/离线),自然语言处理。

 

开发环境架构

包含IDE,编译环境,远程支持,通讯支持与其他大量功能性支持软件,并可以根据不同的工作角色制定不同的环境,以便排除干扰,更加快速有效的进入工作状态。

项目的关键问题是沟通,个性化的工具妨碍——而不是促进沟通。开发和维护公共的通用编程/项目管理工具有很多的好处。

1.建立具有鲜明特色与强大实用性的自有开发环境,展示一个软件龙头企业在企业技术沉淀中的深厚功力和规范性。

2.建立行政流程以规范和约束开发环境管理。

3.划分相关职能以保持对开发环境的维护

4.建立多种培训机制以促进新员工能够迅速投入工作。如固定新员工开发环境熟悉培训机制,建立企业讲解&培训视频库,小组内互助&沟通。

 

过程管理架构

1.过程方法

对多家企业软件生命周期中使用的过程方法进行调查了解到,大部分优秀的软件企业对于过程方法十分重视,且存在针对不同项目合理运用不同的过程方法。项目经理对于过程方法的理解与运用常常关系到项目的成败。

目前核心的管理模型/过程方法主要分为三大类:CMMI,RUP,敏捷。

CMMI作为软件质量体系的标准,软件企业必须具备的资质,具有文档齐全,流程规范等优势,对于大型核心项目有较大优势,其劣势在于灵活度不足,无法很好的满足日益变化的需求。

RUP由Rational公司(被IBM收购,目前是IBM 软件集团旗下之第五大软件品牌)提出,采用迭代开发模式,四个阶段,九大核心工作流,明确的角色划分与文档规划,可裁剪配置的开发过程。目前被大量的软件厂商作为最核心的过程方法使用。

敏捷(Agile)为了满足队伍小型化和需求快速变化而产生的目前最流行的过程方法。XP(Extreme Programming)通过简单的四个核心价值(沟通(Communication)、简单(Simplicity)、反馈(Feedback)和勇气(Courage))与十二条最佳实践从研发的角度提出了最简单直接的开发方式。XP的形态特殊,从编程的角度描述方法与原则,加入了SCRUM之后,加强了从行政体制方面的支持,从而形成了完整的敏捷开发的过程方法体系。

 

过程方法一定不是万金油,针对不同的企业特点,甚至不同项目,都有必要对过程方法进行合理的裁剪与整合。对于目前公司的情况,大型核心项目可以使用CMMI,这些往往决定了企业的战略方向,稳健的过程方法最为合适。大部分中小型项目均可采用 RUP+敏捷 的过程方法,即遵守RUP的核心阶段和工作流,但是迭代周期和开发的基本原则根据敏捷,并挑战整合部分敏捷方法中的最佳实践。这样的策略用于面对市场需求的快速变化,同时也能很好的保障企业在软件生产中的产品价值保存和技术经验积累。

 

2.过程方法自动化支持

针对不同的过程方法,往往有若干的软件产品用以快速自动化的实施。如实施CMMI时所使用到的DEVSUITE产品。完整体系的支持产品往往在应用于某套固定方法有着良好的效果,但容易存在流程生硬,无法与开发环境更好结合形成了信息孤岛,改进困难等缺点。一套优秀的过程方法支持软件,需要和开发环境(如IDE等)良好结合,并且易于调整以应对过程方法的变化,同时没有复杂冗余的过多细节流程以便容易被开发人员学习和掌握。

产品涉及方面:项目计划、项目需求管理、软件配置管理、自动集成、自动产品发布、代码审核、代码质量管理等。

 

 

企业产品架构

1.产品/产品需求流程补充,产品立项时的立项报告中应当包含市场、竞争对手、对手产品、风险等分析。

2.领域模型与概念,在特定的行业中可以即使关注领域专家的动态,以便构建正确的领域模型,确定产品的发展方向和形态的正确性。

3.对于特定产品的领域概念及相关技术发展需要深入了解,如舆情分析系统,需要进行了一定的市场调查,跟进了当前领域专家的报告,参考国内外多项相关项目的设计理念和原则。对于目前市场状况、未来的方向、目前的技术实力等要有比较清晰的概念

4.坚持以市场为导向的原则,在商务部门与研发部门之间搭建积极的沟通桥梁,研发部门的计划根据实际市场需求进行调整。产品的发布配合市场的要求,达到利益最大化。

 

 

企业人件架构

企业自身环境除了常见的软件(Software),硬件(Hardware)以为,还应当加入人件(Peopleware)。之前的种种,如过程方法、技术架构积累、知识分享等均是为了将整个企业构建成为一部精密的机器,无论缺少什么重要零件均可以快速修复,但是人员流失所造成的损失是巨大的。目前公司有着良好的软硬件环境,技术部门作为发动机,若在针对技术性员工有特别的规划和关心,必然能够增强在整个市场中的竞争力,对企业自身的发展也是有良好的推进作用。

公司可以按照职位和员工自身的情况规划发展路线,明确技术目标。开发进化角色基本按照软考标准,程序员-高级程序员-软件设计师-系统分析师-系统架构师,程序员-高级程序员-项目经理。

在技术部门内部,可以定期组织交流心得、新技术等。(在SCRUM中实际上有一些比较好的行政手段可以借鉴参考)

由于软件技术部门的特殊性,一些应用于生产线的行政制度可能能够讨论出更好的实施方案,避免员工单方面的错误认识引发消极的工作态度。

由于有一定经验,而且公司技术架构建设的需要,能够很好的协助企业进行技术架构全方面的介绍和培训。而且我自身也很希望参与到企业文化的建设工作中去,鼓励技术人员之间的技术交流与沟通。

 

posted @ 2012-03-29 16:27 一酌散千忧 阅读(1279) | 评论 (0)编辑 收藏

Example 2-2. A program for finding the maximum recorded temperature by year from NCDC weather records

#!/usr/bin/env bash

for year in all/*

do

  echo -ne `basename $year .gz`"\t"

  gunzip -c $year | \

    awk '{ temp = substr($0, 88, 5) + 0;

           q = substr($0, 93, 1);

           if (temp !=9999 && q ~ /[01459]/ && temp > max) max = temp }

         END { print max }'

done

 

使用linux脚本打印每年最高温度,先解释一下该脚本几个注意点。

脚本目的是发现每年的最高温度,第一句for year in 后的all/*表示在名称为all的文件夹下每年度的温度信息都以 1990.gz 方式存在。使用gunzip方式解压并打印,对打印的内容使用awk函数进行处理,获取最大温度,单个文件处理完毕后打印max

 

在上一篇中获取的数据包是这样,年度为文件夹,当中包含若干个温度详情文件。

E:\testData\1990\010010-9999-1990.gz

E:\testData\1990\010014-9999-1990.gz

E:\testData\1990\010015-9999-1990.gz

E:\testData\1990\010016-9999-1990.gz

 

从后面Appendix C的描述中得知,实际上作者对这样的数据进行了处理,因为hadoop在处理大量的小文件时无法达到很高的效率,因此作者使用hadoop将小文件合并,并且给出了代码。

 

我比较希望能够使用脚本处理,将所有的gz解压之后,合并成为一个文件,打包成gz的格式,这样就能完全符合之前那段脚本的处理方式。所以,脚本如下:

packyear

#! /bin/sh

# /usr/data/packyear

 

# unzip all gz files in data

for yeards in data/*

do

       # unzip all gz files in year directory

       for gzfile in $yeards/*

       do

              gunzip $gzfile

       done

      

       # cat all content to year file

       cat $yeards/* | head -2 >> $yeards.tc

 

       # remove year directory

       rm -rf $yeards

       mv $yeards.tc $yeards

 

       # zip the tc file

       gzip $yeards

done

 

根据实际路径改写的计算最大温度的脚本

maxyear

#! /bin/sh

# /usr/data/ maxyear

 

for year in /usr/data/*

do

  basename $year .gz

  gunzip -c $year | \

    awk '{temp=substr($0, 88, 5)+0;

        q=substr($0, 93, 1);

        if(temp !=9999 && q ~ /[01459]/ && temp > max) max = temp}

      END {print max}'

done

这个脚本最终显示出来会是:

1990

3

这样的格式。由于对数据结构的不熟悉,所以不确定显示出来的数据是否正确,但是基本的脚本和数据操作方式就是这样了。

posted @ 2012-03-29 16:21 一酌散千忧 阅读(468) | 评论 (0)编辑 收藏

Hadoop: The Definitive GuideHadoop权威指南),第十六页中提到了测试数据来源来自于National Climatic Data Center (NCDC, http://www.ncdc.noaa.gov/)。在下面使用Unix Tool编写脚本时使用到的文件格式如下:

 

For example, here are the first entries for 1990:

% ls raw/1990 | head

010010-99999-1990.gz

010014-99999-1990.gz

010015-99999-1990.gz

010016-99999-1990.gz

010017-99999-1990.gz

010030-99999-1990.gz

010040-99999-1990.gz

010080-99999-1990.gz

010100-99999-1990.gz

010150-99999-1990.gz

 

对于数据的来源很困惑,不知道如何下载。google之后在http://lucene.472066.n3.nabble.com/The-NCDC-Weather-Data-for-Hadoop-the-Definitive-Guide-td3736774.html 这篇帖子中发现方法。现在记录一下

连接http://www.ncdc.noaa.gov/


注意到左边的
Free Data

点击后转到的页面向下拉,在Free Data B中友一个完全免费的FTP(红框所示)


 

提供ftp地址为:ftp://ftp3.ncdc.noaa.gov/pub/data/noaa/

我使用了FileZillahttp://dl.pconline.com.cn/html_2/1/89/id=5826&pn=0.html)进行下载


1w多个文件,可能是不需要完全下载的。

(完)

posted @ 2012-03-28 10:32 一酌散千忧 阅读(1693) | 评论 (0)编辑 收藏

仅列出标题
共2页: 上一页 1 2