??xml version="1.0" encoding="utf-8" standalone="yes"?> 当今NoSQL领域中有很多有力的竞争者通过多种方式来处理v量数据问题。其中重要的解决Ҏ之一是MongoDB。MongoDB是面向文档的q构化存储ҎQ用JSON格式来展现、查询和修改数据?/span> MongoDB文档相当完备Q扩展规模与安装一L单。它提供冗余、切片、烦引以及map/reduce{概忉|持。MongoDB的开源社区非常大且非常活跃。MongoDB在很多大型品中被实际运用,如:Disney, Craigslist, Foursquare, Github 和SourceForge。MongoDB是一个开源项目,?/span>10gen.com建立q维护,该公司由DoubleClick的前L行h员创立。同Ӟ10gen也提供了极好的商业支持与参与?/span> MongoDB作ؓ一个可用NoSQLҎh很多优势。我刚开始接触NoSQL数据库了解了一pdZJava的方案,q且׃大量的时间来弄懂什么是列家族,Hadoop与HBase的关p,ZooKeeper到底是什么。当我终于全部清楚之后,发现Cassandra与HBase实是对于NoSQL领域非常可靠、可信赖的解x案。但与其他的解决Ҏ相比QMongoDB让我在能够开始写代码之前Q不用理解那么多的概c?/span> 与其他Y件相|MongoDB也存在缺陗经q一D|间用MongoDBQ我列Dl历qƈ需要注意的一些事情,我成?#8220;Gotchas”Q?/span> MongoDB基本是用JavaScript客户端命令行E序来进行复杂Q务管理的Q如数据整合和简单信息处理,~程都是完全使用JavaScript语言来的。本文中Q我们会展示命o行的使用CZ。现在有大量的MongoDB客户端品提供,q且由MongoDBC来支持驱动。通常每种~程语言都有驱动Qƈ且所有流行的语言都有包括Q一些不那么行的也包含在内。这文章展CZ使用MongoDB的Java驱动Qƈ使用一个ORM库(MJORMQ与之进行比较?/span> 在解决的众多有意思的问题中,最q?span>NoSQL数据存储在开发者中主要的问题趋势就是对象关pL。对象关pL就是将传统中保存在关系型数据库中的持久化数据映ؓ在应用程序中使用的对象。这使得~程语言使用h更加畅和自然?/span> MongoDB面向文档的架构得它非常适合对象关系映射Q因为文档本w就是以对象形式存储的。可惜没有太多的MongoDB的Java对象关系映射库,但是q是有一些,?/span>morphia-(A type-safe Java library for MongoDB)Q?span> spring-data(SpringData目的MongoDB实现) q些ORM库大量用了注解Q因Z些原因对我不适合Q其中最重要的就是这些被注解的对象在多个目中的兼容性问题。这让我开始了mongo-Java-orm 或?"MJORM" (发音 me-yorm)目Q一个MongoDB的Java对象关系映射目。MJORM是在MIT许可之下Qƈ且在发布在了google code project。项目采?span>maven构徏Qƈ且maven构g仓库托管于google code版本控制服务器。MJORM的最新可用发布版本ؓ0.15Q已l由一些项目用与生环境中?/span> Maven的用者首先应当在pom.xml中加入MJORM的maven仓库Q得MJORM构g可用?/span> 然后加入依赖: q样可以在应用中引?span>MJORM代码。假如没有用mavenQ则你需要手动下载MJORM的pom.xml中列丄所有依赖?/span> 依赖已经导入Q可以开始编码了。我们从POJO开? 我们在这个对象模型中的描q是Q作者有ID、姓和名Q书有ID、ISNB、标题、描q和作者?/span> 你可能注意到书的id属性是一个字W串Q这是ؓ了适应MongoDB的对象IDcd。MongoDB的ID是一?2字节的二q制值显CZؓ一个十六进制的字符丌ӀMongoDB要求集合中的每个文档都必L一个唯一idQ但不要求一定要是ObjectId。目前MJORM只支持ObjectIdQƈ且显CZؓ字符丌Ӏ?/span> 你也可能注意CAuthor没有id字段。这是因为Book是它的父文档Q因此不需要有id。记住,MongoDB只要求集合中的文档在根别的id?/span> 下一个步骤就是徏?span>XML映射文gQMJORM能够MongoDB文档转换为对象。我们ؓ每个文档创徏一个对象作为示范,无论所有的映射攑֜一个XML文g中还是分开都是可以的?/span> q些映射文g能够很好的自解释?/span> 可以?span>google code的MJORM目主页中查看XML映射文g的更多细节描q?/span> 我们创徏了数据模型以及映文Ӟ使得MJORM可以从MongoDB序列号以及反序列号POJO。我们可以进行一些有意思的事情了,首先打开MongoDB的链接: 建立好了 首先我们要获?span>10gen驱动提供的DB对象实例。然后用DB?/span> 首先建立 我们来看看假如不?span>MJORM而直接?0gen的Java驱动Q如何?/span> 下面q行对象的查?span>: 敏锐的读者会注意?span>Bookq没有指定AuthorQ仍然保存了。这归咎于MongoDB的结构不敏感的特性。我们不能要求集合中的文档包含所有属性(id属性是必须的)Q所有在MongoDB中没有Author的Book是可以的。我们现在ؓBookd一个Authorq且更新一下: 现在Book包含了AuthorQƈ且在MongoDB中持久化了。现在在命o行查看了BookQ?/span> 可以看到持久化的Book中已l包含了author。不使用MJORM来操作一遍: 对于 希望q篇文章?span>MongoDB和MJORM的亮Ҏ所展示。MongDB是一个优U的呃NoSQL数据存储Q有着大量优秀的特性,会是NoSQL市场中长期竞争者。若你会在一个Java目中用MongoDBQ希望你也能够考虑使用MJORM作ؓ你的ORM框架。十分欢q大家提交特性需求、错误异常报告、文档和源码修正?/span> Brian Dilley 是一个经验丰富的高工程师以及项目领|?/span>Java/Java EE /Spring Framework/Linux内部l构理解和管理有着过13q的l验?/span>Brian对于创业公司有很多经验,推向市场Q构?/span>/l护产品{。他?/span>Iaas?/span>cloud?/span>PHP?/span>Linux的专Ӟ熟悉产品的采购、安装及配置定义Q以及公司的软硬件架构包括负载均衡、数据库、微博等。可?/span>follow Brian?/span> Twitter ?/span>MongoDB介绍
MongoDB ?/span> NoSQL: ~陷与优?/span>
MongoDB, 命o行与驱动
介绍 MJORM: MongoDB?/span>ORMҎ
开始?/span>ORM
加入MJORM ?/span>
<repository>
<id>mjorm-webdav-maven-repo</id>
<name>mjorm maven repository</name>
<url>http://mongo-Java-orm.googlecode.com/svn/maven/repo/</url>
<layout>default</layout>
</repository>
<dependency>
<groupId>com.googlecode</groupId>
<artifactId>mongo-Java-orm</artifactId>
<version>0.15</version>
</dependency>
建立 POJOs
class Author {
private String firstName;
private String lastName;
// ... setters and getters ...
}
class Book {
private String id;
private String isbn;
private String title;
private String description;
private Author author;
// ... setters and getters ...
}
创徏XML映射文g
Author.mjorm.xml
:<?xml version="1.0"?>
<descriptors>
<object class="Author">
<property name="firstName" />
<property name="lastName" />
</object>
</descriptors>
Book.mjorm.xml
:<?xml version="1.0"?>
<descriptors>
<object class="Book">
<property name="id" id="true" auto="true" />
<property name="isbn" />
<property name="title" />
<property name="description" />
<property name="author" />
</object>
</descriptors>
descriptors
元素是根元素Q必d含在每个映射文g中。在它下面是object
元素定义了文档与之对应的cR?/span>Object
包含?/span>
property
元素主要用于描述POJO中的属性以及这些属性如何与MongoDB中的文档惛_应?/span>property
元素臛_必须包含一?/span>name
属性,q个元素是POJO和MongoDB的文档中的属性名U?/span>column
属性则是可选的Q用于特定一个在MongoDB文档中的可选属性名U?/span>property
元素当中?span>id属性应该是对象的唯一识别。一个对象只能有一?/span>property
元素包含id属性?/span>auto
的设|会使得MJORM在持久化时ؓ该属性自动生成一个倹{?/span>整合POJO?/span>XML
Mongo mongo = new Mongo(
new MongoURI("mongodb://localhost/mjormIsFun")); // 10gen driver
Mongo
对象是由10gen~写的Java驱动提供的。示例中q接了一个本地的MongoDB实例中的mjormIsFun数据库。接下来我们创徏MJORM ObjectMapper
。目?/span>ObjectMapper
在MJORM中的唯一实现是XmlDescriptorObjectMapper
Q用XMLl构描述信息。可能之后会增加Ҏ解或其他l构定义的支持?/span>XmlDescriptorObjectMapper objectMapper = new XmlDescriptorObjectMapper();
mapper.addXmlObjectDescriptor(new File("Book.mjorm.xml"));
mapper.addXmlObjectDescriptor(new File("Author.mjorm.xml"));
XmlDescriptorObjectMapper
q且加入了映文件。接下来建立由MJORM提供?/span>MongoDao
对象的实例?/span>DB db = mongo.getDB("mjormIsFun"); // 10gen driver
MongoDao dao = new MongoDaoImpl(db, objectMapper);
ObjectMapper
建立MongoDao
。我们准备开始持久化数据Q徏立一?/span>Book
然后保存到MongoDB中?/span>Book book = new Book();
book.setIsbn("1594743061");
book.setTitle("MongoDB is fun");
book.setDescription("...");
book = dao.createObject("books", book);
System.out.println(book.getId()); // 4f96309f762dd76ece5a9595
Book
对象q且填|然后调用MongoDao
?/span> createObject
ҎQ将Book
对象传入"books
" 的集合中。MJORM会按照之前的xml映射文g?/span>Book
转换?/span>DBObject
(q是10gen的Java驱动使用的基本类?Qƈ保存一个新的文档进"books
" 集合。MJORMq回Book对象Ӟid属性会被填充。请注意QMongoDB默认是不需要在使用前徏立数据库或集合的Q系l会在需要时自动创徏Q这可能会造成某些困扰。在MongoDB的命令行中查看Book对象大概如下Q?/span>> db.books.find({_id:ObjectId("4f96309f762dd76ece5a9595")}).pretty()
{
"_id": ObjectId("4f96309f762dd76ece5a9595"),
"isbn": "1594743061",
"title": "MongoDB is fun",
"description": "..."
}
createObject
ҎQ?/span>Book book = new Book();
book.setIsbn("1594743061");
book.setTitle("MongoDB is fun");
book.setDescription("...");
DBObject bookObj = BasicDBObjectBuilder.start()
.add("isbn", book.getIsbn())
.add("title", book.getTitle())
.add("description", book.getDescription())
.get();
// 'db' is our DB object from earlier
DBCollection col = db.getCollection("books");
col.insert(bookObj);
ObjectId id = ObjectId.class.cast(bookObj.get("_id"));
System.out.println(id.toStringMongod()); // 4f96309f762dd76ece5a9595
Book book = dao.readObject("books", "4f96309f762dd76ece5a9595", Book.class);
System.out.println(book.getTitle()); // "MongoDB is fun"
readObject
ҎҎl定文档的id从指定的集合中读取文档,转换为对象(再次使用映射文gQƈq回?/span>Author author = new Author();
author.setFirstName("Brian");
author.setLastName("Dilley");
book.setAuthor(author);
dao.updateObject("books", "4f96309f762dd76ece5a9595", book);
> db.books.find({_id:ObjectId("4f96309f762dd76ece5a9595")}).pretty()
{
"_id": ObjectId("4f96309f762dd76ece5a9595"),
"isbn": "1594743061",
"title": "MongoDB is fun",
"description": "..."
"author": {
"firstName": "Brian",
"lastName": "Dilley"
}
}
Author author = new Author();
author.setFirstName("Brian");
author.setLastName("Dilley");
book.setAuthor(author);
DBObject bookObj = BasicDBObjectBuilder.start()
.add("isbn", book.getIsbn())
.add("title", book.getTitle())
.add("description", book.getDescription())
.push("author")
.add("firstName", author.getFirstName())
.add("lastName", author.getLastName())
.pop()
.get();
DBCollection col = db.getCollection("books");
col.update(new BasicDBObject("_id", bookObj.get("_id")), bookObj);
MongoDao
Ҏ的深入讨论已l超Z本文的范围。对于将MJORM有兴用于实际项目中的用户强烈徏议了解一下MJORM目提供的相x档,或?/span>MongoDao
接口提供的相关用法?/span>ȝ
作?/span> Bio
]]>
转变了数据管理方式的技术正是虚拟化。低成本存储、云计算?/span>NoSQL数据库以?/span>Hadoop。当我们提v虚拟化时Q已l远q超Zؓ一台物理机器提供一套Y件实例这一概念。时至今日,我们可以虚拟化服务器、存储以及网l。所有这些虚拟化意味着我们不再被这些物理条件所限制Q能够迅速构建物理环境以支持我们特定时刻的特定需求。当面对Gb?/span>Tb?/span>Pb{数据量的处理需求时Q我们基本能摆脱l构化的数据仓库。我们不在需要仅仅ؓ了发掘业务的某一斚w而徏立一个特D的环境了?/span>
低成本存储在业务的数据存储方面节省了开支。高昂的存储成本会得企业寻扑֜限定规模的数据之上进行关键业务分析的ҎQ这样得如何选择最重要的数据变得十分关键,而且q限制了pȝ能够处理的数据的质量?/span>
负面影响便是业务最l可能面临很的选择Q因为没有够的历史数据提供从而识别一个有效关键模式。或者因为高昂的投入使得业务被停止,而用常规惯例来识别模式?/span>
云计ؓ那些需要通过量数据源在合理旉范围内生结果的需求提供了一个可用的方式。v量数据处理需要两点:Ҏ存储,CPU。高速网l很有帮助,但是待会我们会看到在发掘软g在处理v量数据时Q它q是系l的瓉。弹性存储意味着企业不会在期望操作的数据规模或类型上受到限制Q降低了使用数据仓库无法获取最佳结果的风险。更多的CPU使得l果能够在期望的旉范围内更快的被交付?/span>
NoSQL提供了v量数据的支持Q但与传l的关系型数据库没有兌。而且大部?/span>NoSQL数据库是开源的Q无L付购买证书等费用?/span>NoSQL对于表结构有着惊h的灵zL,无须随着pȝ的改q而不断修改完善定义?/span>NoSQL可以支持不同数据源的合ƈ查看Q从而成?/span>EII之后另一个备选方案,q或许是NoSQL最重要的方面了?/span>
NoSQL内置了数据冗余与分布式数据存储机制。v量数据的最大问题之一是盘dQ?/span>NoSQL通过数据分布至一pd节点来缓解这个问题。当一个查询请求发出时Q这些节点能够ƈ行查询自w节点,而不是仅仅依靠一块磁盘,一个磁盘阵列或一条网l连接等Q数据查询能够在节省了读写开支之后变得更加迅速?/span>
最l,我们来讨?/span>HadoopQ集合了上述所有技术力量与一w的用于和分析数据的框架。有些h可能认ؓHadoop是一?/span>NoSQL技术,实际?/span>Hadoop是一个分布组件的java框架Q用于分?#8220;吃大?#8221;Q此处也双关Hadoop是以创立者的儿子l自q一个大象玩兯v的名字)的工?#8212;—每次一口?/span>
Hadoop自n实际上与待处理数据是各自独立的。它大型查询Q务分解ؓ的q行查询dQ然后收集结果,q整合出{案q回l用戗?/span>Hadoop相对?/span>NoSQL来说是一个ƈ行查询框Ӟ通过云计驱动节点,q行在低成本存储及虚拟化技术之上?/span>
Kicking的知识回?/span>
?/span>EIIW一ơ作为最佛_践出C2003-2004q_关键要素是无需再移动数据了。当时大部分的数据中心仍然运行于低速网l中Q有限的I间用于复制数据。之后,EII成ؓ了当时可用技术和问题域中最优秀的解x案?/span>EII的某些方面的优秀即在v量数据中也是很显著的?/span>
EII的优点之一是处理过E{Ud数据所在地。v量数据方案的关键架构要素之一是处理过E{Ud数据所在地Q而不是{UL据?/span>EII中的一个重要原则就是用数据归属地的查询功能。这实践就是构建靠q数据源|络?/span>Web ServiceQ能够徏立v通用查询接口Q但只针Ҏ地数据库q行查询。我们通过开攄ZWeb的接口解决了数据的专有格式的问题Q从而得多个数据子集能够迅速的整合q以l一模式展示?/span>
有了低成本存储和10G|络之后Q我们就不必那么担心数据冗余与数据迁U,但还是有其他问题存在的,数据仓库无法保数据的原始性便是其中之一。在EII中,我们从原始数据源获取数据视?#8220;黄金准则”Q这样就能够保证信息未被修改q,且是准确的?/span>
Big Data要求数据必须转移到新的物理位|,q样可信d又成Z问题?/span>EII的那些获取基U数据的最佛_践仍然是相关而且重要的。实际上Q那些ؓEII设计开发的Web Services接口最l在Big Data的启用中扮演主要角色?/span>
当然Q讨论数据管理不能不涉及到安全问题?/span>EII在安全领域中q是过?/span>Big Data。技术上来说Q?/span>Big Data在数据集成方面更加高效与敏捷Q但是大部分~少了固有的安全性,因ؓ在设计上会加大处理的隑ֺ。所以,可能要由源系l来担Qh据访问安全方面的责Q。因?/span>EII直接在源pȝ中查询数据,所以必要求有适当的授权,否则查询将p|?/span>
上述关于安全讨论描述的是内在的安全控制情c将讉K权限控制列表集成q数据库是非常合理的Q这确保安全能够作为查询的一部分q行l护。然后,一旦能够直接查?/span>NoSQL数据源,意味着能够自由的访问你所有的数据?/span>
ȝ
引用老的Virginia Slims的广告中的台词:“我们已经历很长的路途了Q宝贝儿Q?#8221;文中讨论到的技术的发展已经?/span>21世纪W二?/span>10q中的的数据解决Ҏ产生了巨大的影响。商业化与小型化扫除了一些思想体系上的障碍Q得架构师能够专注于问题本w,而不是寻找一些实用及可实现的问题解决Ҏ。构?/span>10000个节点的处理引擎Q能够在数秒内处?/span>PbU别的数据量Q却只消耗每时几便士,q就是数据处理的好前景?/span>
有了q些新工P我们p重新考虑如何推进数据理。ؓ何数据无法被很好地被l护整合Qƈ且需要花Ҏ万美元。数据管理几乎是每个大中型企业的心病。数据管理曾l在存储、管理、访问、整合以及查询上p巨大Q但是今后不再会是这样了?/span>
关于作?/span>
JP Morgenthal 是在IT{略与云计算斚w的世界专家之一。他在企业复杂问题域的解x案实施上有着25q的l验?/span>JP Morgenthal以其在技术方面的深度和广度,有利的支持他在企业问题域中的敏感度。他在集成、Y件开发和云计是一位让人尊敬的作者,同时也是InfoQ在引领云计算斚w的编辑,q且参与?#8220;云计:评估风险”目?/span>
原文?/span>接:http://www.infoq.com/articles/DataIntegrationFromEIItoBigData
原文引用Qhttp://www.infoq.com/articles/tips-to-developers-starting-on-large-apps
假设你是正在开发和l护一个包?/span>2000个类q用了很多框架?/span>Java开发者。你要如何理解这些代码?在一个典型的Java企业目组中,大部分能够帮你的高工程师看h都很忙。文档也很少。你需要尽快交付成果,q向目l证明自q能力。你会如何处理这U状况?q篇文字为开始一个新目?/span>Java开发者提供了一些徏议?/span>
1 不要试图一下子搞懂整个目
好好考虑一下,Z么理解项目代码是W一位的Q大部分情况是你被要求修复一?/span>bug或者加强系l已有功能。你要做的第一件事情不是理解整个项目的架构。当寚w目进行维护时Q?/span>q样Q理解整个项目架构)可能会对你造成巨大的压力?/span>
即便是有着10q可靠编E经验的Java开发者可能也没有理解目的核心工作机Ӟ管他们可能已经在这个项目工作超q一q_假设他们q原始开发h员)。比如,对于认证机制或事务管理机制?/span>
他们是怎么做的Q他们对于自p责的部分非常了解Qƈ且能够交付h值给组。每天的交付价D比了解一些以后还不确定有没有的东襉K要的多?/span>
2 x于尽快交付h?/span>
那我是否定了你对于项目架构理解的热情了么Q完全不。我只是要求你尽早的交付价|一旦你开始一个项目,搭徏了开发环境,你就不应该花一两周旉才交付什么,无论他的规模大小。假如你是一个有l验的程序员却两周都没有M交付Q你的经理怎么会知道你是真的在工作q是在看新闻?/span>
所以交付可以大家都轻松v来。不要认Z能够做有价值的交付前必ȝ解整个项目。这是完全错误的。加一D?/span>javascript的验证代码对业务很有h|l理能够通过你的交付辑ֈ对你的信仅R这栯够向上领导证明你的贡献以及员工价倹{?/span>
日复一日,在你不断修复bug及增强功能之后,p够慢慢开始理解项目架构。不要低估对pȝҎ面面理解旉要花费的旉。花3-4天理解认证机Ӟ2-3天理解事物管理。这些都是依靠之前的怼目的经历,但关键还是要花时间才能透彻的理解。要在日常工作中挤出旉Q不要向l理要求特定的时间来做这些?/span>
找找目是否有一些不断维护的单元试用例。有效的单元试用例是理解大型项目代码的很好途径。单元测试能够帮助理解代码片D,包括一个单元的外部接口Q单元如何被调用以及q回内容Q及其内部实玎ͼ调试单元试比调试整个实际用例简单许多)?/span>
你如果能够很好的理解一些内容,写一些笔讎ͼ或者画一些类图、时序图、数据模型图Q以便你或日后其他的开发者维护?/span>
3 l护大型目所必须的技?/span>
你能从事当前的工作,必然已经h良好?/span>java技术。我们来谈谈能够让你在新目中良好表现的其他技能。大部分旉Q你在项目中的Q务是修复bug和增强功能?/span>
有两很重要的技能能够协助你l护大型目代码?/span>
3.1 能够q速发现需要的c?/span>
在Q何维护活动中Q无论是修复bug或增强功能,W一个动作就是识别出当前修复或增强的用例中调用的cR当你定位到需要修复或增强的类/ҎQ就已经完工了一半?/p>
3.2 能够分析变更的媄?/span>
当你在完成必要的修改或增强工作后Q最重要的就是要认你的修改没有破坏代码的其他部分。你要用你的java技术及对其他框架的理解扑և变更可能影响的部分。下面有两个单的例子详细描述了最后提及的情况Q?/p>
aQ当cA的equals()Ҏ变更后,调用一个保护A实例的List的contains()Ҏ时就会被影响到。若Java知识不够Q很难考虑到这L影响?/p>
bQ在一个web目中,我们假设“user id”保存在session中。一个新入程序员可能?#8220;user id”中加入一些信息作为bug修复的方法,但是却不知道会媄响到那些兌“user id”的用例?/p>
当你提高了如上两个技能,管你对目不是非常了解Q但大部分的l护d会变得简单很多。若你修复一个bugQ你会定位ƈ修复q个bugQƈ且保证变更不会破坏项目的其他部分。若你增强或加入一个特性,基本上你只需要模仿现有的Ҏ用相似的设计?/p>
在一个在UK行项目中Qؓ什?#8220;查看账户摘要”?#8220;查看交易历史”的设计需要巨大的差别呢?如果你理解了“查看账户摘要”的设计,完全可以模仿开发出“查看交易历史”的功能?/p>
׃复bug和增强来_你不必完全理解所?000个类的工作内容和代码如何q行来推动系l。你若有上面的技能,p很快定位需要修改的代码的部分,使用良好的java和框架技能修复,保证变更不会破坏目的其他部分ƈ交付Q尽你可能只知道一部分项目的设计?/p>
4 使用工具扑ֈ需要的变更内容以及变更产生的媄?/span>
l箋我们快交付的主题,你应当寻N些能够通过量的了解目但能帮助你尽快实施交付的工具作ؓ辅助?/p>
4.1 q速发现需要变更内容的工具
无论是修复bugq是pȝ增强Q首先都要找到该用例调用的你需要修改的cdҎ。基本有两种方式理解一个用例的工作方式Q静态代码分析和q行时分析?/p>
源码分析l计扫描所有代码ƈ且展C类之间的关pR市Z有很多设备与工具。比如:ArchitexaQ?AgileJQ?UModelQ?Poseidon{?/p>
所有的静态代码分析工L点在于无法确切展C用例中cLҎ的运行时调用情况。因此Java新加入了Ҏ,如回调机Ӟcallback patternsQ。如静态分析工h法推断出当页面提交按钮被点击时哪个Servlet被调用了?/p>
q行时分析工兯够展C类和方法在用例q行时的状态。工具包括:MaintainJQ?DiverQjSondeQJava Call Tracer{。这些工具可以捕莯行时的堆栈状态,q以此ؓ一个用例生成序列图和类图?/p>
序列囑ֱCZ该用例在q行时所有调用的Ҏ。若你在修复一个bugQ那q个bug很可能就是这些被调用的方法之一?/p>
若你在增强已有功能,利用序列囄解调用流E然后再修改。可能是新增一个验证,修改DAO{?/p>
若你在新增功能,扑ֈ一些相似的Ҏ,利用序列囄解调用流E然后模仿开发新功能?/p>
要小心挑选运行时分析工具。信息过多是q类工具的主要问题。选择一些提供简单过滤无效信息ƈ能够方便的查看各U视囄工具?/p>
4.2 q速发现需要变更内容的工具
若单元测试有效,可以通过q行单元试发现变更有没有破坏其他测试用例。有效维护ƈ且覆盖大型企业应用的单元试q是比较的。下面有一些针对该情况的工兗?/p>
仍然是有两种技术静态代码分析和q行时分析可以用。市Z有很多静态代码分析工具可用。如QLattix, Structure101, Coverity, nWire and IntelliJ's DSM?/p>
l定一个变更后的类Q上q工具均可识别对该类存在依赖的类的集合。开发者需要根据这些信?#8220;猜测”可能产生影响的用例,因ؓq些工具无法展示q行时类之间的调用关pR?/p>
市场上的可以用于q行时媄响分析的工具q不多,除了MaintainJ。MaintainJ先捕获在一个用例中调用的所有类和方法。当所有用例的上述信息都被捕获之后Q就很容易发现类的变更对用例的媄响。MaintainJ能够有效工作的前|条件就是项目的所有用例都应当先运行一遍,以便能够获得q行时的依赖关系?/p>
MQ目前你在迅速准分析变更媄响方面,q是可以从工具中获得有限的帮助。首先根据需要实施一些媄响分析,然后Ҏ自己或小l其他高U成员评审来判断变更的媄响。你可能需要上面提到的工具对你的判断进行反复确认?/p>
5 对上q内容的两个忠告
5.1 不要降低代码质量
Z快速交付,所以没有全盘理解架构,但绝不能以降低代码质量ؓ条g。下面是一些你可能因ؓ只考虑快速交付而引发的代码质量问题?/p>
因ؓ修改代码涉及到很多的依赖Q所以新增代码相对而言风险较小。例如,?个用例都调用了某个方法。ؓ了改q某个用例,你需要修改这个方法的实现。最单的做法是复制q个ҎQ重命名Q然后在改进的用例中调用新方法。千万不要这么做。代码冗余绝Ҏ非常有害的。尝试对Ҏq行包装或者重写,甚至是直接修改,然后重新试所有用例,通常停下来想一惻I然后亲手d施,是一个比较好的方式?/p>
另一个例子是?#8220;private”Ҏ改ؓ“public”Q得别的类也可以调用。尽量不要将非必ȝ部分暴露出来。假如ؓ了更好的设计需要重构,应当着手去做?/p>
大部分应用都有确定的l构和模式来实施。修复或增强E序Ӟ认你没有偏这L模式。若对约定不定Q请其他的高U开发者来审核你的变更。若你必d一些违背约定的实施Q尽量放|于一个规模较的cMQ一?00行代码的cM的私有函数应当不会媄响应用的整体设计Q?/p>
5.2 不要停止深入理解目架构
按照文章列出的方式,假设你能够在寚w目了解较的情况下进行交付ƈ以此持箋下去Q可能你会停止对目架构的深入了解。这样从长远角度来说对你的职业生涯没有帮助。当你的l验增加Ӟ你应当承担比较大的模块Q务。如构徏一个完整的新特性或者修攚w目的一些基设计{较大的改进。当你能够做q些改进Ӟ你对目的整体架构应该相当了解。文中列丄Ҏ是让你在最短的旉内提升自己,而不是阻止你完整理解整个目?/p>
6 l论
整篇文章集中在对目q行必要了解的前提下q行快速交付。你可以在不降低代码质量的前提下q么做?/p>
若修复一个bugQ迅速定位ƈ修复。有必要可以使用q行时分析工兗若新增一个特写,可以L怼特写Q理解流E(有必要用工Pq编写?/p>
或许q些听v来很单,但是实用吗?当然。但前提是你有良好的java技术以及对框架_了解才能先修改代码,然后对变更媄响进行分析。对变更影响的分析比实施变更需要更多的技巧。你可能需要高U开发h员协助你分析变更影响?/p>
大约?0%的IT可操作预用于简单的bug修复和功能增强。根据文中的Q对于维护活动中的经费的节省应当q是很有帮助的?/p>
作者Choudary Kothapalli 也是MaintainJ目的徏立者?/p>
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.