﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-BlueDavy之技术Blog-随笔分类-Java</title><link>http://www.blogjava.net/BlueDavy/category/1366.html</link><description>不懂理论只懂实战的粗人。</description><language>zh-cn</language><lastBuildDate>Sun, 25 Nov 2007 13:07:32 GMT</lastBuildDate><pubDate>Sun, 25 Nov 2007 13:07:32 GMT</pubDate><ttl>60</ttl><item><title>《面向软件错误构建可靠的分布式系统》读后感</title><link>http://www.blogjava.net/BlueDavy/archive/2007/11/25/162998.html</link><dc:creator>BlueDavy</dc:creator><author>BlueDavy</author><pubDate>Sun, 25 Nov 2007 11:00:00 GMT</pubDate><guid>http://www.blogjava.net/BlueDavy/archive/2007/11/25/162998.html</guid><wfw:comment>http://www.blogjava.net/BlueDavy/comments/162998.html</wfw:comment><comments>http://www.blogjava.net/BlueDavy/archive/2007/11/25/162998.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/BlueDavy/comments/commentRss/162998.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/BlueDavy/services/trackbacks/162998.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 这篇文档是erlang创始者之一的Joe Armstrong所编写的博士论文，由段先德翻译、邓辉审校，感兴趣的同学可以从以下地址下载：<br> http://erlang-china.org/study/joe-armstrong_thesis_cn.html<br>Erlang在业界已经引起了不小的轰动，通读了下这篇博士论文，翻译的质量很高，:)，所以读起来非常的顺畅，论文的内容对于erlang初学者而言绝对是堪称经典，写的非常的不错，点出了erlang的强项并详细的进行了解释，感谢翻译论文的段先德和邓辉的工作。<br>Erlang以天生的支持并发、分布式和容错而闻名，由于erlang的诞生是为交换机而服务的，因此在并发、分布式、容错、动态代码升级等方面是实现的非常好的，其目前主要是应用在erission的交换机上，这对于erlang的那些天生的特性也是个很好的证明。<br>通过阅读这篇博士论文，让我对了erlang有了部分的认识，由于目前尚未实践过，只能根据论文本身对自己理解的erlang做个阐述。<br>Erlang采用的是虚拟机的方式，这个虚拟机和java的虚拟机类似&nbsp;&nbsp;<a href='http://www.blogjava.net/BlueDavy/archive/2007/11/25/162998.html'>阅读全文</a><img src ="http://www.blogjava.net/BlueDavy/aggbug/162998.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/BlueDavy/" target="_blank">BlueDavy</a> 2007-11-25 19:00 <a href="http://www.blogjava.net/BlueDavy/archive/2007/11/25/162998.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SQLUnit quick start guide</title><link>http://www.blogjava.net/BlueDavy/archive/2007/11/08/159124.html</link><dc:creator>BlueDavy</dc:creator><author>BlueDavy</author><pubDate>Thu, 08 Nov 2007 08:59:00 GMT</pubDate><guid>http://www.blogjava.net/BlueDavy/archive/2007/11/08/159124.html</guid><wfw:comment>http://www.blogjava.net/BlueDavy/comments/159124.html</wfw:comment><comments>http://www.blogjava.net/BlueDavy/archive/2007/11/08/159124.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/BlueDavy/comments/commentRss/159124.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/BlueDavy/services/trackbacks/159124.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: SQLUnit是一个用于对存储过程进行单元测试的工具，其实也可以用于做针对数据库数据、性能的测试等，延续了xUnit家族的一贯特性和风格，只不过它的测试是以xml的方式来编写，但原则仍然和xUnit家族其他产品一样，强调的是输出和预期的比较，SQLUnit的文档比较的少，由于官方站上并没有提供类似其他开源工具的quick start guide，就写了这篇quick start guide以便大家快速的使用sqlunit，至于SQLUnit的高级用法还是得去多看看sqlunit.sf.net官方站上的文档。<br>为了让大家能快速的开始入门使用SQLUnit，将介绍SQLUnit环境的搭建、如何编写一个单元测试、如何运行。<br><br>&nbsp;&nbsp;<a href='http://www.blogjava.net/BlueDavy/archive/2007/11/08/159124.html'>阅读全文</a><img src ="http://www.blogjava.net/BlueDavy/aggbug/159124.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/BlueDavy/" target="_blank">BlueDavy</a> 2007-11-08 16:59 <a href="http://www.blogjava.net/BlueDavy/archive/2007/11/08/159124.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java调用Oracle EXP备忘</title><link>http://www.blogjava.net/BlueDavy/archive/2006/11/22/82909.html</link><dc:creator>BlueDavy</dc:creator><author>BlueDavy</author><pubDate>Wed, 22 Nov 2006 14:43:00 GMT</pubDate><guid>http://www.blogjava.net/BlueDavy/archive/2006/11/22/82909.html</guid><wfw:comment>http://www.blogjava.net/BlueDavy/comments/82909.html</wfw:comment><comments>http://www.blogjava.net/BlueDavy/archive/2006/11/22/82909.html#Feedback</comments><slash:comments>7</slash:comments><wfw:commentRss>http://www.blogjava.net/BlueDavy/comments/commentRss/82909.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/BlueDavy/services/trackbacks/82909.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 一眼看过去相信大家都知道用Runtime.getRuntime().exec来调用，我的需求就是：<br>调用Oracle EXP命令完成备份，并返回生成的备份文件名，这个备份文件会很快在其他的地方被使用。<br>采用Runtime.getRuntime().exec我们都知道，需要处理它的InputStream，以避免出现执行的命令输出的信息过多使得进程被堵死，OK，按照这样的方法写出来的代码执行后却碰到了问题.....&nbsp;&nbsp;<a href='http://www.blogjava.net/BlueDavy/archive/2006/11/22/82909.html'>阅读全文</a><img src ="http://www.blogjava.net/BlueDavy/aggbug/82909.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/BlueDavy/" target="_blank">BlueDavy</a> 2006-11-22 22:43 <a href="http://www.blogjava.net/BlueDavy/archive/2006/11/22/82909.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>备忘：解决ajax获取页面直接显示乱码的方法</title><link>http://www.blogjava.net/BlueDavy/archive/2006/08/15/63633.html</link><dc:creator>BlueDavy</dc:creator><author>BlueDavy</author><pubDate>Tue, 15 Aug 2006 03:04:00 GMT</pubDate><guid>http://www.blogjava.net/BlueDavy/archive/2006/08/15/63633.html</guid><wfw:comment>http://www.blogjava.net/BlueDavy/comments/63633.html</wfw:comment><comments>http://www.blogjava.net/BlueDavy/archive/2006/08/15/63633.html#Feedback</comments><slash:comments>10</slash:comments><wfw:commentRss>http://www.blogjava.net/BlueDavy/comments/commentRss/63633.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/BlueDavy/services/trackbacks/63633.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 大家都知道，xmlhttp在通信时采用的是utf编码，而国内很多网页的信息都是采用gbk编码，所以当直接通过ajax去连接网页，并将获取到的信息直接显示的话就会出现乱码的现象，有些时候无法改变服务器端网页的编码(例如获取别的网站的天气预报信息)，在这种时候就只能在客户端通过js做编码的工作了，下面这段js就是用于将服务器端返回的gbk编码字符串转换为utf编码字符串：&nbsp;&nbsp;<a href='http://www.blogjava.net/BlueDavy/archive/2006/08/15/63633.html'>阅读全文</a><img src ="http://www.blogjava.net/BlueDavy/aggbug/63633.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/BlueDavy/" target="_blank">BlueDavy</a> 2006-08-15 11:04 <a href="http://www.blogjava.net/BlueDavy/archive/2006/08/15/63633.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>缓存漫谈</title><link>http://www.blogjava.net/BlueDavy/archive/2006/06/02/50076.html</link><dc:creator>BlueDavy</dc:creator><author>BlueDavy</author><pubDate>Fri, 02 Jun 2006 15:38:00 GMT</pubDate><guid>http://www.blogjava.net/BlueDavy/archive/2006/06/02/50076.html</guid><wfw:comment>http://www.blogjava.net/BlueDavy/comments/50076.html</wfw:comment><comments>http://www.blogjava.net/BlueDavy/archive/2006/06/02/50076.html#Feedback</comments><slash:comments>9</slash:comments><wfw:commentRss>http://www.blogjava.net/BlueDavy/comments/commentRss/50076.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/BlueDavy/services/trackbacks/50076.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 缓存是在提升系统响应时常用的一种技术，在我之前的blog中也提及过好几次这部分的技术，今天还是想从缓存涉及的一些方面再次的去谈谈，在系统缓存上通常采用的是有页面缓存、处理缓存和数据缓存这三种具体的类别，应该说这三种缓存在实现上还是稍有不同，尽管底层的缓存实现是一样的。&nbsp;&nbsp;<a href='http://www.blogjava.net/BlueDavy/archive/2006/06/02/50076.html'>阅读全文</a><img src ="http://www.blogjava.net/BlueDavy/aggbug/50076.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/BlueDavy/" target="_blank">BlueDavy</a> 2006-06-02 23:38 <a href="http://www.blogjava.net/BlueDavy/archive/2006/06/02/50076.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Foundations Of Ajax读后感</title><link>http://www.blogjava.net/BlueDavy/archive/2006/05/23/47711.html</link><dc:creator>BlueDavy</dc:creator><author>BlueDavy</author><pubDate>Tue, 23 May 2006 13:20:00 GMT</pubDate><guid>http://www.blogjava.net/BlueDavy/archive/2006/05/23/47711.html</guid><wfw:comment>http://www.blogjava.net/BlueDavy/comments/47711.html</wfw:comment><comments>http://www.blogjava.net/BlueDavy/archive/2006/05/23/47711.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/BlueDavy/comments/commentRss/47711.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/BlueDavy/services/trackbacks/47711.html</trackback:ping><description><![CDATA[
		<p>Foundations Of Ajax，Ajax领域中的经典书籍，还是决定看看，今天趁有些时间便翻阅了一下，总体而言，这本书写的还是不错的，在douban上我写了这么一段评价：“对于ajax新手而言，这绝对是本好书，可以快速的让你了解ajax涉及的技术，如何去使用ajax以及ajax的一些缺点；对于ajax老手来说，这本书固然有些简单，但我相信会带给你更加系统化的ajax知识。”<br />该书从历史、ajax相关的技术、带来的优点以及缺点、ajax例子、ajax开发工具箱以及ajax框架几个方面进行讲解，系统的梳理了ajax的整个技术体系，整个ajax的技术体系就这么清晰的暴露在了大家的眼前，就像这本书的书名一样，这本书对于ajax整个技术体系只是稍有提及，但并没有深入，作为ajax的基础书籍来说，我觉得这样就够了，而且这样很好，其实觉得就像在使用mindmanager一样，先列出的是比较粗略的，之后才是对于每个节点的深入，这本书就等于给ajax新手一个ajax的全面印象，至于里面涉及到的各种技术可以再去专门研究，^_^，在这样的引导的情况下，可以让希望使用ajax的同学们能非常好的进入这个领域...<br />就像书中所说的一样，ajax固然是带来了很多的提升，但在目前的情况下不一定是所有用户都能接受的，所以不能在项目中武断的全面使用，要先去评估下用户的接受度，其次是目前业界在ajax到底如何去应用还没有研究的非常清楚，这也是为什么现在没什么好的ajax框架的原因，这也就意味着如果在项目中要大幅度的使用ajax还是有一定的技术风险的...<br />Ajax相比其他的技术思想比较有利于推广的地方就在于它采用的是现有成熟的技术，尽管从架构角度上来讲确实带给了传统mvc冲击，但从技术角度却没有给目前的开发人员带来多大的冲击，这就使得它很利于推广了，不过真正要全面推行还得依靠一个良好的ajax框架.....</p>
<img src ="http://www.blogjava.net/BlueDavy/aggbug/47711.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/BlueDavy/" target="_blank">BlueDavy</a> 2006-05-23 21:20 <a href="http://www.blogjava.net/BlueDavy/archive/2006/05/23/47711.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>项目杂感</title><link>http://www.blogjava.net/BlueDavy/archive/2006/04/24/42895.html</link><dc:creator>BlueDavy</dc:creator><author>BlueDavy</author><pubDate>Mon, 24 Apr 2006 13:38:00 GMT</pubDate><guid>http://www.blogjava.net/BlueDavy/archive/2006/04/24/42895.html</guid><wfw:comment>http://www.blogjava.net/BlueDavy/comments/42895.html</wfw:comment><comments>http://www.blogjava.net/BlueDavy/archive/2006/04/24/42895.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.blogjava.net/BlueDavy/comments/commentRss/42895.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/BlueDavy/services/trackbacks/42895.html</trackback:ping><description><![CDATA[再次做项目，感觉颇多，项目和产品其实都有应对变化的部分，项目更在乎功能的实现以及对于需求的应变能力，产品更在乎的是通用性的高度抽象、开放性以及基础设施的建设上，产品比项目更依赖规划人员对于通用性需求的挖掘上，而项目则更依赖需求人员对于客户的需求的挖掘上。<br />做外地项目的时候项目经理的作用比在公司做项目时的项目经理的作用会更加的突出，项目经理的表率作用、看法、做法其实很大程度上都影响到整个团队，所以感觉在外地项目中项目经理非常重要，很大程度上决定了项目的成败。<br />今天和项目中的成员聊起PP，^_^，得到了成员的认可，难得呀，想着以前在一个项目中做PP的时候，项目成员那都是极力的反对呀，PP得到认可的原因是在现有的项目中开发计划总是出现推迟的现象，但其实负责此任务的成员每天都在加班，而且加班到很晚，那么到底是为什么呢？归根结底就是工作效率低，并不是因为该成员能力不足，PP从很大程度上都能提高工作效率，但PP确实对成员的性格很有要求，否则很容易出问题，对于PP我认为的几点好处：<br />1、能够让整个团队形成团结一致的作战能力和工作氛围；<br />2、能够保证团队编写风格一致的代码；<br />3、能够保证代码编写的质量；<br />4、能够极大的提高工作效率；<br />5、能够快速准确的评价团队成员的能力；<br />^_^，其实遵照一个“工作时工作，玩的时候玩，学习时候学习”的基本原则，就会过的挺好的，其实一个开发人员每天能高效写4个小时我觉得已经挺不错了，其实PP是能真正的发挥整个团队成员能力的手段，也能足够的去保证工作效率和质量，只是推广PP必然也会受到很大的阻力，不过其实这就是一种习惯而已，不要带着敌对的心态，试着去接受，也许你也会喜欢上PP的，呵呵...<br />^_^，项目的一个不好的地方就是要投N多时间关注在功能需求的实现上，缺少了对于技术的关心，呵呵，这个是技术人员的观点而已...<img src ="http://www.blogjava.net/BlueDavy/aggbug/42895.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/BlueDavy/" target="_blank">BlueDavy</a> 2006-04-24 21:38 <a href="http://www.blogjava.net/BlueDavy/archive/2006/04/24/42895.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Maven、Hibernate升级小贴士</title><link>http://www.blogjava.net/BlueDavy/archive/2006/04/20/42119.html</link><dc:creator>BlueDavy</dc:creator><author>BlueDavy</author><pubDate>Thu, 20 Apr 2006 03:00:00 GMT</pubDate><guid>http://www.blogjava.net/BlueDavy/archive/2006/04/20/42119.html</guid><wfw:comment>http://www.blogjava.net/BlueDavy/comments/42119.html</wfw:comment><comments>http://www.blogjava.net/BlueDavy/archive/2006/04/20/42119.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/BlueDavy/comments/commentRss/42119.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/BlueDavy/services/trackbacks/42119.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 记录一下Maven 1升级到Maven 2、Hibernate 2.1升级到Hibernate 3的一些注意事项，^_^，以备后用，毕竟以前的系统很多都是基于Maven 1和Hibernate 2.1的。&nbsp;&nbsp;<a href='http://www.blogjava.net/BlueDavy/archive/2006/04/20/42119.html'>阅读全文</a><img src ="http://www.blogjava.net/BlueDavy/aggbug/42119.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/BlueDavy/" target="_blank">BlueDavy</a> 2006-04-20 11:00 <a href="http://www.blogjava.net/BlueDavy/archive/2006/04/20/42119.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Service-Oriented Component Model(SOCM)</title><link>http://www.blogjava.net/BlueDavy/archive/2006/04/15/41268.html</link><dc:creator>BlueDavy</dc:creator><author>BlueDavy</author><pubDate>Sat, 15 Apr 2006 13:33:00 GMT</pubDate><guid>http://www.blogjava.net/BlueDavy/archive/2006/04/15/41268.html</guid><wfw:comment>http://www.blogjava.net/BlueDavy/comments/41268.html</wfw:comment><comments>http://www.blogjava.net/BlueDavy/archive/2006/04/15/41268.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/BlueDavy/comments/commentRss/41268.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/BlueDavy/services/trackbacks/41268.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 继续以OSGI R4的Declarative Services(DS)来讲讲Service-Oriented Component Model(SOCM)，SOCM对于现有的Component-Oriented Model或者是Service-Oriented Model来说到底有什么不同的地方，到底DS能给我们带来什么样的好处呢？&nbsp;&nbsp;<a href='http://www.blogjava.net/BlueDavy/archive/2006/04/15/41268.html'>阅读全文</a><img src ="http://www.blogjava.net/BlueDavy/aggbug/41268.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/BlueDavy/" target="_blank">BlueDavy</a> 2006-04-15 21:33 <a href="http://www.blogjava.net/BlueDavy/archive/2006/04/15/41268.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>基于元数据和RIA的开发框架</title><link>http://www.blogjava.net/BlueDavy/archive/2006/04/11/40492.html</link><dc:creator>BlueDavy</dc:creator><author>BlueDavy</author><pubDate>Tue, 11 Apr 2006 09:03:00 GMT</pubDate><guid>http://www.blogjava.net/BlueDavy/archive/2006/04/11/40492.html</guid><wfw:comment>http://www.blogjava.net/BlueDavy/comments/40492.html</wfw:comment><comments>http://www.blogjava.net/BlueDavy/archive/2006/04/11/40492.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.blogjava.net/BlueDavy/comments/commentRss/40492.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/BlueDavy/services/trackbacks/40492.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 目前做的一个Web开发框架，基于元数据和RIA，把现在所做的效果贴出来给大家看看，同时也简单的再说说基于元数据和RIA的开发，^_^&nbsp;&nbsp;<a href='http://www.blogjava.net/BlueDavy/archive/2006/04/11/40492.html'>阅读全文</a><img src ="http://www.blogjava.net/BlueDavy/aggbug/40492.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/BlueDavy/" target="_blank">BlueDavy</a> 2006-04-11 17:03 <a href="http://www.blogjava.net/BlueDavy/archive/2006/04/11/40492.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Declarative Services――Service-Oriented Component Model</title><link>http://www.blogjava.net/BlueDavy/archive/2006/04/07/39880.html</link><dc:creator>BlueDavy</dc:creator><author>BlueDavy</author><pubDate>Fri, 07 Apr 2006 09:27:00 GMT</pubDate><guid>http://www.blogjava.net/BlueDavy/archive/2006/04/07/39880.html</guid><wfw:comment>http://www.blogjava.net/BlueDavy/comments/39880.html</wfw:comment><comments>http://www.blogjava.net/BlueDavy/archive/2006/04/07/39880.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/BlueDavy/comments/commentRss/39880.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/BlueDavy/services/trackbacks/39880.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Jeff在EclipseCon 2006那篇介绍Equinox的PPT中提到的Declarative Services(文中全部采用DS简称)的用法让人极度被吸引，但同时又产生怀疑，想起以前自己看过DS好像不是这样的，没这么强，便再次翻阅了OSGI R4中的DS的章节，以验证Jeff的说法，^_^，仔细看过DS章节后，确实为Declarative Services的强大而感到高兴，DS是一个面向服务的组件模型，从组件模型层次上去看，它超越了传统的组件模型，在组件模型描述的完备性上有了很大的进步，例如在组件服务的依赖上、组件服务的延迟加载上、组件服务的多样性控制上、组件服务的配置上以及组件服务的生命周期管理上，不过DS只能在OSGI容器中使用，这尽管看上去可能是个弱点，但作为OSGI规范中的一部分，这无可厚非，其思想值得很多目前Component Model的开源框架值得思考和学习，如感兴趣，请阅读OSGI R4中DS章节。&nbsp;&nbsp;<a href='http://www.blogjava.net/BlueDavy/archive/2006/04/07/39880.html'>阅读全文</a><img src ="http://www.blogjava.net/BlueDavy/aggbug/39880.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/BlueDavy/" target="_blank">BlueDavy</a> 2006-04-07 17:27 <a href="http://www.blogjava.net/BlueDavy/archive/2006/04/07/39880.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hibernate获取数据方式与缓存使用</title><link>http://www.blogjava.net/BlueDavy/archive/2006/04/06/39539.html</link><dc:creator>BlueDavy</dc:creator><author>BlueDavy</author><pubDate>Thu, 06 Apr 2006 02:49:00 GMT</pubDate><guid>http://www.blogjava.net/BlueDavy/archive/2006/04/06/39539.html</guid><wfw:comment>http://www.blogjava.net/BlueDavy/comments/39539.html</wfw:comment><comments>http://www.blogjava.net/BlueDavy/archive/2006/04/06/39539.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/BlueDavy/comments/commentRss/39539.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/BlueDavy/services/trackbacks/39539.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Hibernate获取数据的方式有不同的几种，其与缓存结合使用的效果也不尽相同，而Hibernate中具体怎么使用缓存其实是我们很关心的一个问题，直接涉及到性能方面。&nbsp;&nbsp;<a href='http://www.blogjava.net/BlueDavy/archive/2006/04/06/39539.html'>阅读全文</a><img src ="http://www.blogjava.net/BlueDavy/aggbug/39539.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/BlueDavy/" target="_blank">BlueDavy</a> 2006-04-06 10:49 <a href="http://www.blogjava.net/BlueDavy/archive/2006/04/06/39539.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hibernate的延迟属性抓取</title><link>http://www.blogjava.net/BlueDavy/archive/2006/04/05/39491.html</link><dc:creator>BlueDavy</dc:creator><author>BlueDavy</author><pubDate>Wed, 05 Apr 2006 14:45:00 GMT</pubDate><guid>http://www.blogjava.net/BlueDavy/archive/2006/04/05/39491.html</guid><wfw:comment>http://www.blogjava.net/BlueDavy/comments/39491.html</wfw:comment><comments>http://www.blogjava.net/BlueDavy/archive/2006/04/05/39491.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.blogjava.net/BlueDavy/comments/commentRss/39491.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/BlueDavy/services/trackbacks/39491.html</trackback:ping><description><![CDATA[
		<p>再次犯了没有仔细看Hibernate Reference的错误，在Hibernate 3以上版本都支持对于property设置lazy="true"，但一直我都以为只要设置了就可以实现的，今天和jindw讨论的时候才知道原来不是这样，^_^，赶快做了下试验，确实，即使对于property设置了lazy="true"，但在调用获取了po中的任意非主键属性时其他所有的property也就被加载了，也就是说lazy没有生效，到底怎么回事呢，翻阅Hibernate Reference才明白了这个问题：<br />property<br />(7)lazy (可选，默认为false) 指定实例变量第一次被访问时，这个属性是否延迟抓取(需要运行时字节码增强)<br />其实看这部分会在最后那句需要运行时字节码增强上迷糊，在hibernate reference中还有一句这样的话：<font size="2"><font color="#cc0033">“Hibernate</font>也不需要使用任何编译期处理，比如字节码<font color="#cc0033">增强</font>操作，它独立的使用Java反射机制和<font color="#cc0033">运行时</font>类<font color="#cc0033">增强</font>（通过<font color="#cc0033">CGLIB</font>)。”<br /></font><font size="3"> 这就非常迷糊了，因为这里已经说了比如字节码增强操作....<br />不过还好在Hibernate Reference中有个专门的章节来解释property lazy的问题，这个章节就是使用延迟属性抓取，在这里才算是完全看明白了：<br />“属性的延迟载入要求在其代码构建时加入二进制指令，如果你的持久类代码中未含有这些指令，Hibernate将会忽略这些属性的延迟设置，仍然将其直接载入。”<br />看完这段就明白了，也就是说要在编译期对代码进行字节码增强，关于编译期进行字节码增强的实现具体见Hibernate Reference，里面列出了一个采用ant task完成编译时字节码增强的实现。<br /><br />想明白后怀疑是不是Hibernate Reference中文版中翻译错了？写的应该是需要编译时字节码增强吧，果然，查阅了一下Hibernate Reference英文版，上面写的就是requires build-time bytecode instrumentation...<br />不过Hibernate Reference中文版中component部分的lazy翻译的又是对的，那里的翻译就是需要编译时字节码增强，^_^<br /></font></p>
<img src ="http://www.blogjava.net/BlueDavy/aggbug/39491.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/BlueDavy/" target="_blank">BlueDavy</a> 2006-04-05 22:45 <a href="http://www.blogjava.net/BlueDavy/archive/2006/04/05/39491.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>读EclipseCon2006相关PPT有感</title><link>http://www.blogjava.net/BlueDavy/archive/2006/04/05/39438.html</link><dc:creator>BlueDavy</dc:creator><author>BlueDavy</author><pubDate>Wed, 05 Apr 2006 09:12:00 GMT</pubDate><guid>http://www.blogjava.net/BlueDavy/archive/2006/04/05/39438.html</guid><wfw:comment>http://www.blogjava.net/BlueDavy/comments/39438.html</wfw:comment><comments>http://www.blogjava.net/BlueDavy/archive/2006/04/05/39438.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/BlueDavy/comments/commentRss/39438.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/BlueDavy/services/trackbacks/39438.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: EclipseCon2006已经结束一段时间了，最近才抽出时间去down下相关感兴趣的PPT来看看，受益不少，N多大师的演讲另人拍案叫绝，不过也有几个PPT让我看的有所疑问，摘录几个PPT的读后感，^_^&nbsp;&nbsp;<a href='http://www.blogjava.net/BlueDavy/archive/2006/04/05/39438.html'>阅读全文</a><img src ="http://www.blogjava.net/BlueDavy/aggbug/39438.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/BlueDavy/" target="_blank">BlueDavy</a> 2006-04-05 17:12 <a href="http://www.blogjava.net/BlueDavy/archive/2006/04/05/39438.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hibernate实践</title><link>http://www.blogjava.net/BlueDavy/archive/2006/03/27/37582.html</link><dc:creator>BlueDavy</dc:creator><author>BlueDavy</author><pubDate>Mon, 27 Mar 2006 04:47:00 GMT</pubDate><guid>http://www.blogjava.net/BlueDavy/archive/2006/03/27/37582.html</guid><wfw:comment>http://www.blogjava.net/BlueDavy/comments/37582.html</wfw:comment><comments>http://www.blogjava.net/BlueDavy/archive/2006/03/27/37582.html#Feedback</comments><slash:comments>26</slash:comments><wfw:commentRss>http://www.blogjava.net/BlueDavy/comments/commentRss/37582.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/BlueDavy/services/trackbacks/37582.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 在实际项目中使用Hibernate有两年多了，在两年多的实践过程中既体验到了Hibernate带来的N多好处，同时也碰到不少的问题，特写此篇文章做个总结，记录自己在Hibernate实践中的一些经验，希望对于新使用Hibernate的朋友能有个帮助，避免走过多的弯路。<br>阅读本文前建议至少拥有Hibernate的一些基本知识，因为本文不会去详细介绍相关的基本知识，最好就是先用Hibernate开发了一个HelloWorld，^_^。<br>根据自己所经历的项目中使用Hibernate所涉及的范围，本文从开发环境、开发、设计、性能、测试以及推荐的相关书籍方面进行讲述，本篇文档不会讲的非常细致，只是根据自己在实践时的经验提出一些建议，关于细致以及具体的部分请参阅《Hibernate Reference》或推荐的相关书籍章节。<br>此文档的PDF版本请到此下载：<br>http://www.blogjava.net/Files/BlueDavy/Hibernate实践.rar<br>本文允许转载，但转载时请注明作者以及来源。&nbsp;&nbsp;<a href='http://www.blogjava.net/BlueDavy/archive/2006/03/27/37582.html'>阅读全文</a><img src ="http://www.blogjava.net/BlueDavy/aggbug/37582.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/BlueDavy/" target="_blank">BlueDavy</a> 2006-03-27 12:47 <a href="http://www.blogjava.net/BlueDavy/archive/2006/03/27/37582.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>续谈基于RIA和元数据进行企业应用开发</title><link>http://www.blogjava.net/BlueDavy/archive/2006/03/21/36614.html</link><dc:creator>BlueDavy</dc:creator><author>BlueDavy</author><pubDate>Tue, 21 Mar 2006 05:22:00 GMT</pubDate><guid>http://www.blogjava.net/BlueDavy/archive/2006/03/21/36614.html</guid><wfw:comment>http://www.blogjava.net/BlueDavy/comments/36614.html</wfw:comment><comments>http://www.blogjava.net/BlueDavy/archive/2006/03/21/36614.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/BlueDavy/comments/commentRss/36614.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/BlueDavy/services/trackbacks/36614.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 在上篇中简单的描述了下在我现在开发的东西中关于元数据的设计，在这篇中将结合目前实际的系统的截图来说明关于元数据的具体定义、UI方面的控制以及基于RIA和元数据的系统实现。&nbsp;&nbsp;<a href='http://www.blogjava.net/BlueDavy/archive/2006/03/21/36614.html'>阅读全文</a><img src ="http://www.blogjava.net/BlueDavy/aggbug/36614.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/BlueDavy/" target="_blank">BlueDavy</a> 2006-03-21 13:22 <a href="http://www.blogjava.net/BlueDavy/archive/2006/03/21/36614.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>分层与分模块开发</title><link>http://www.blogjava.net/BlueDavy/archive/2006/03/19/36101.html</link><dc:creator>BlueDavy</dc:creator><author>BlueDavy</author><pubDate>Sun, 19 Mar 2006 13:11:00 GMT</pubDate><guid>http://www.blogjava.net/BlueDavy/archive/2006/03/19/36101.html</guid><wfw:comment>http://www.blogjava.net/BlueDavy/comments/36101.html</wfw:comment><comments>http://www.blogjava.net/BlueDavy/archive/2006/03/19/36101.html#Feedback</comments><slash:comments>24</slash:comments><wfw:commentRss>http://www.blogjava.net/BlueDavy/comments/commentRss/36101.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/BlueDavy/services/trackbacks/36101.html</trackback:ping><description><![CDATA[分层与分模块开发，是开发时经常选用的两种方式，应该说分模块开发是较多被采用的方式，但一直以来都觉得其实分层方式自己是比较欣赏的方式，对于两种开发方式分别的看法是：<br /><strong><font style="BACKGROUND-COLOR: #ffffff" color="#008000">分层开发</font></strong><br />优点：<br />1、保持系统分层结构<br />      分层开发在这点上无疑是可以保证的，同时有利于保证系统层次的职责的清晰以及分离。<br />2、面向接口的编程<br />      由于采用分层开发，各层次之间采用接口依赖的方式就更容易被执行了。<br />缺点：<br />1、容易造成瓶颈现象<br />      由于分层开发各个承担人员的任务难度不一样，很容易形成瓶颈现象。<br />2、对于系统设计的要求更高<br />      这点应该说不能算是缺点。<br />3、容易出现扯皮现象<br /><strong><font color="#008000">分模块开发</font></strong><br />优点：<br />1、系统功能更容易被完成<br />      由于采用分模块开发，开发人员从头到尾负责，一定程度上来讲减少了沟通以及协调成本，使得系统功能能够被更容易的完成。<br />缺点：<br />1、容易造成系统的分层结构缺失<br />      通常在项目实际的赶工情况下，很容易形成系统的分层结构缺失的情况，开发人员为了完成功能完全不顾分层，不顾层次职责的分离的保证，这点在实际的项目中往往不是那么好控制。<br />2、面向接口编程的贯彻不力<br />      这点也通常是由于上面的原因，当然，其实这里面最根本的原因是开发人员本身的素质不够高....<br /><br />在开发人员水平参差不齐的情况下，我认为分层开发方式更有利于保证系统的质量，尽管在具体实施的时候可能会碰到一些问题，希望能听听采用过分层开发方式的朋友们的看法。<br /> <img src ="http://www.blogjava.net/BlueDavy/aggbug/36101.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/BlueDavy/" target="_blank">BlueDavy</a> 2006-03-19 21:11 <a href="http://www.blogjava.net/BlueDavy/archive/2006/03/19/36101.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>也论基于元数据和RIA进行企业应用开发</title><link>http://www.blogjava.net/BlueDavy/archive/2006/03/18/35946.html</link><dc:creator>BlueDavy</dc:creator><author>BlueDavy</author><pubDate>Sat, 18 Mar 2006 07:31:00 GMT</pubDate><guid>http://www.blogjava.net/BlueDavy/archive/2006/03/18/35946.html</guid><wfw:comment>http://www.blogjava.net/BlueDavy/comments/35946.html</wfw:comment><comments>http://www.blogjava.net/BlueDavy/archive/2006/03/18/35946.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/BlueDavy/comments/commentRss/35946.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/BlueDavy/services/trackbacks/35946.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 看了caoxg在广州Bea User Group上讲的《利用元数据和RIA简化企业应用程序的开发》的PPT，很有感触，说说自己对于其中几点的看法，同时也谈谈自己在现在的项目中的实际的关于metadata的做法。&nbsp;&nbsp;<a href='http://www.blogjava.net/BlueDavy/archive/2006/03/18/35946.html'>阅读全文</a><img src ="http://www.blogjava.net/BlueDavy/aggbug/35946.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/BlueDavy/" target="_blank">BlueDavy</a> 2006-03-18 15:31 <a href="http://www.blogjava.net/BlueDavy/archive/2006/03/18/35946.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>AJAX中Onepage的注意事项</title><link>http://www.blogjava.net/BlueDavy/archive/2006/03/16/35562.html</link><dc:creator>BlueDavy</dc:creator><author>BlueDavy</author><pubDate>Thu, 16 Mar 2006 02:55:00 GMT</pubDate><guid>http://www.blogjava.net/BlueDavy/archive/2006/03/16/35562.html</guid><wfw:comment>http://www.blogjava.net/BlueDavy/comments/35562.html</wfw:comment><comments>http://www.blogjava.net/BlueDavy/archive/2006/03/16/35562.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/BlueDavy/comments/commentRss/35562.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/BlueDavy/services/trackbacks/35562.html</trackback:ping><description><![CDATA[在采用Ajax进行系统实现时，通常会采用onepage的方式进行实现，自己目前也在一个实际的项目中使用着，总体感觉有几点是在使用onepage时特别要注意的：<BR>1、js事件的有效范围的控制<BR>&nbsp;&nbsp;&nbsp;&nbsp; 由于一直在同一个页面，这个时候特别要注意对于js事件有效范围的一个控制，我觉得是需要同样的模仿出以前在传统的MVC模式下的session范围/request范围等，当然，js事件的有效范围则要控制的更加细致，甚至要控制到域级。<BR>&nbsp;&nbsp;&nbsp;&nbsp; 之前发布的一个js版本的事件管理器中是缺乏对于范围的控制的，在使用中出现了不少的问题，现在正在逐步的调整，等以后完全调整好后再发布一个版本。<BR>2、资源有效范围的控制<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 其实这个和上面的问题类似，由于不切换页面，往往在组件交互的过程中采取的都是清空目前容器的方式，这个时候要特别注意....<BR><BR>觉得onepage的方式固然在理论上来讲是比较好的，但在实际开发上还是比较希望采用类似的之前切换页面的方式，这个在buffalo中有支持，switchView和switchPart，觉得那样开发起来的话会觉得比较的习惯，而且不用去担心关于js事件/资源有效范围这个因素，不过我这点我不确定buffalo是否能做到，因为我看buffalo好像也没有在某个范围级别的资源清除的处理....<BR>dwr新的版本，也就是1.1中集成了对于pageflow的支持，这是个不错的feature，^_^，有空的时候去摸索摸索，^_^<img src ="http://www.blogjava.net/BlueDavy/aggbug/35562.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/BlueDavy/" target="_blank">BlueDavy</a> 2006-03-16 10:55 <a href="http://www.blogjava.net/BlueDavy/archive/2006/03/16/35562.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>基于Equinox开发系统的总结</title><link>http://www.blogjava.net/BlueDavy/archive/2006/03/12/34930.html</link><dc:creator>BlueDavy</dc:creator><author>BlueDavy</author><pubDate>Sun, 12 Mar 2006 13:32:00 GMT</pubDate><guid>http://www.blogjava.net/BlueDavy/archive/2006/03/12/34930.html</guid><wfw:comment>http://www.blogjava.net/BlueDavy/comments/34930.html</wfw:comment><comments>http://www.blogjava.net/BlueDavy/archive/2006/03/12/34930.html#Feedback</comments><slash:comments>9</slash:comments><wfw:commentRss>http://www.blogjava.net/BlueDavy/comments/commentRss/34930.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/BlueDavy/services/trackbacks/34930.html</trackback:ping><description><![CDATA[<P>Equinox，我不想多做介绍，相信很多人都有所了解了，不了解的可具体去<A href="http://www.eclipse.org/equinox">www.eclipse.org/equinox</A>看看。<BR>最近基于equinox做了一个系统，还是碰到了一些问题，当然也得到了在插件体系架构下的不少优点，在这里也做个总结。<BR>总体而言，基于equinox做开发对于大多数java开发人员来说应该不会有太多改变的感觉，最多改变的感觉应该是带给设计师，设计师需要有发挥插件体系架构优点以及减少其带来的缺点的能力，^_^<BR>1、部署不是很方便<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; equinox默认提供的是一个console端的插件部署管理，部署起来需要通过"install reference:file://"这样的方式来安装插件，不是特别的方便。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ^_^，由于我当时使用的时候equinox还没提供osgi中httpservice的实现，便使用了oscar中提供的httpservice的实现，基于这个httpservice的实现写了一个web端的插件管理的工具，呵呵，将来整理后会将这个bundle公布出来，到时大家直接下载就可以用了。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在部署方面还有一个不方便的地方就是不能指定插件的启动顺序，现在equinox是通过config.ini中来实现插件启动顺序的控制的，这个在我的web端的插件管理工具中也提供直接，可直接设定插件的启动顺序。<BR>2、Classpath的问题<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这个问题是我在使用equinox时比较头疼的一个问题，我在bundle中使用了spring IoC container，而由于spring中使用的不是当前类的加载器，导致在加载配置文件的时候会出错，只得直接修改了spring中那些部分的代码，将其改为使用当前类的加载器。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在集成其他一些自己含有classpath的东西的时候也很容易出现这个问题。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 虽然从原理上来讲这个是可以理解的，因为在插件体系结构中每个插件都拥有独立的插件类加载器，这个确实会对集成的有些东西产生影响，抑或我们应该理解为集成的那些东西在这方面设计有缺陷？<BR>3、有利于面向接口编程的执行<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这个应该说是属于插件体系结构的好处，每个插件可以控制自己对外所暴露的包，这个时候就可以只暴露接口所在的包，^_^，呵呵，面向接口的编程就这么被强制的执行了。<BR>4、插件开发的IDE<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这点是我觉得equinox的天然优势，拥有一个eclipse这么优秀的插件开发的IDE，^_^<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 支持了插件的调试...<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 我认为的最重要的一点是它解决了插件依赖的问题，通常在出现project依赖的时候我们都需要引用该project或是该project生成的jar，而在插件体系结构中只需要在插件文件中定义所依赖的包即可，这个就解决了去引用project那样方式引起整个项目工程包混乱和开发不便的现象。 <BR>5、插件的测试<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;这点我想也是大家很关心的，不过大家可以放心，基本没什么不同的，unit test继续使用Mock方式完成所测试的unit的外部依赖的部分，集成测试则需要启动equinox容器，这点应该没什么不能接受的。<BR>6、Bundle和Service的定义<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这个就是插件体系结构带来的一个挑战，如果准确的定义系统中的bundle和service是很关键的一个问题，这对于发挥插件体系结构的bundle级别、service级别的重用性至关重要，同时对于整个项目结构的清晰度也会产生很大的影响，形成bundle的清晰的service依赖结构。<BR>7、面向服务的体系<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 我想这也同样是象equinox这样的插件框架引发使用者的思考，系统采用的应该是一种面向服务的体系，服务才是系统的核心，bundle只是一个管理器而已，这个时候怎么样设计出动态、松散耦合的服务体系是很关键的。<BR><BR>equinox一直都在发展之中，它的maillist一直就非常的热闹，而且现在对于osgi中的service它基本都实现了，也已经开始提供对于servlet container集成的支持，^_^，极度支持equinox，虽然它还需要不断的努力.....<BR>可以看得出，经过我上面的总结，大家其实要担心的是引用一种新的体系结构带来的设计层面的变革，而不是开发实现层面，^_^&nbsp;</P><img src ="http://www.blogjava.net/BlueDavy/aggbug/34930.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/BlueDavy/" target="_blank">BlueDavy</a> 2006-03-12 21:32 <a href="http://www.blogjava.net/BlueDavy/archive/2006/03/12/34930.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>测试</title><link>http://www.blogjava.net/BlueDavy/archive/2006/03/08/34250.html</link><dc:creator>BlueDavy</dc:creator><author>BlueDavy</author><pubDate>Wed, 08 Mar 2006 05:20:00 GMT</pubDate><guid>http://www.blogjava.net/BlueDavy/archive/2006/03/08/34250.html</guid><wfw:comment>http://www.blogjava.net/BlueDavy/comments/34250.html</wfw:comment><comments>http://www.blogjava.net/BlueDavy/archive/2006/03/08/34250.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/BlueDavy/comments/commentRss/34250.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/BlueDavy/services/trackbacks/34250.html</trackback:ping><description><![CDATA[1、测试数据/运行数据的互不影响<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在做测试时，通常都需要生成测试数据，在测试运行完后又要进行测试数据的删除工作，当测试和运行用的是同一个库的情况下就很容易出现测试数据和运行数据互相影响的现象，这个时候在写测试的时候就要特别的注意了，既不能让运行数据影响了测试的结果，又不能让测试数据影响到了运行数据。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 通常来说，为了解决这个问题，会采用测试库和运行库分开的方式，采取这种方式的情况下就比较简单了，不过有些时候还是挺麻烦的，毕竟要创建数据、删除数据。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 还有一种特殊的情况，例如一个这样的项目：<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 项目已经上线运行了，这个时候做了一个新的流程，在部署了新的流程到运行环境后，通常需要在运行环境中测试一下，这个时候问题就出现了，测试数据和运行数据并行，这个时候就要充分的考虑测试数据和运行数据的互不影响。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;当然，上面的项目的情况是一个比较特殊的情况，就像icecloud说的，项目规划的好的话是会有测试环境和运行环境的不同的，测试环境需要和运行环境完全一致，在有新增的东西需要部署到运行环境时先在测试环境进行测试，测试没问题后再通过升级脚本部署到运行环境中。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;这些方法确实是可以解决测试数据/运行数据的互相影响的问题，不过觉得还是有些的麻烦，觉得如果有一个工具可以帮忙避免测试数据/运行数据的互相影响，同时又可以让你在写测试的时候很容易的创建测试数据，又不用担心其他测试数据或运行数据对它造成影响，最后测试数据又可以安全的被清除，^_^，有个这样的工具就好了.........<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 或者说大家在实际中碰到测试数据/运行数据并行的情况下会怎么办呢..<BR>2、单元测试<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 一直以来都实行TDD，不过发现我做单元测试的方法仍然不正确，尽管在测试的基本原则---"测试一定情况下单元的执行是否和预期一致"上是正确的，但进行单元测试的方法并不正确，就像robbin所说，我做的是集成测试，因为我做单元测试时会去把该单元依赖的其他的对象所需要的东西也去进行模拟，这样说起来可能过于生涩了，举个例子吧：<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;有一个服务类，该服务类依赖一个Dao类，通过Dao从数据库中获取相关的信息后进行处理，我以前做单元测试的做法就是首先产生出测试数据，由Dao先将测试数据进行持久，之后再通过调用服务类的方法去执行，"一定的情况"通常都是由测试数据来控制，这点没什么不对，就是控制所测试的单元的输入。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 测试的基本原则都是检查在一定的输入的情况下输出是否符合预期，作为单元测试而言上面的做法不正确的地方就是去产生测试数据并由Dao先持久，其实作为单元测试而言，只需要测试当前对象执行的正确性，也就是说它已经假设了它所依赖的其他的对象产生的结果，这样的单元测试才是有意义的，而且也变得更容易写了，之前我所采用的那种测试其实是集成测试....<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这样说了后其实就很容易理解单元测试了，仍然是上面的服务类，它的单元测试的写法应该是去Mock出Dao执行的结果，当然，这个时候就要模拟Dao在返回几种情况下服务的执行情况了，这个是正常的，就是去控制服务的输入，^_^，这样可以看到，其实在单元测试中是不会出现多少测试数据的情况的，除了Dao，而且也不用去关心其所依赖的对象的执行的正确与否，以及所依赖的对象是不是还依赖别的对象，^_^，可以保证测试的范围就是本单元。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这样做的潜在好处还在于会促进面向接口的编程，^_^<BR>3、集成测试<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 集成测试就是需要创建出所依赖的对象的环境的一种测试方法，其实在有了单元测试的情况下，集成测试就可以完全的从系统的入口进行测试，例如B/S系统来讲，它的入口都是页面，也就是我们可以通过页面来进行测试，这个时候可以看到，测试数据的问题又产生了...<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 当然，对于有些集成测试是需要编写代码的，这个时候就需要创建出入口对象所依赖的对象(以及它所依赖的对象)的环境，最后才能调用入口对象的方法进行测试，这样就完成集成测试了。<img src ="http://www.blogjava.net/BlueDavy/aggbug/34250.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/BlueDavy/" target="_blank">BlueDavy</a> 2006-03-08 13:20 <a href="http://www.blogjava.net/BlueDavy/archive/2006/03/08/34250.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>碰到的一个Hibernate的问题</title><link>http://www.blogjava.net/BlueDavy/archive/2006/02/24/32336.html</link><dc:creator>BlueDavy</dc:creator><author>BlueDavy</author><pubDate>Fri, 24 Feb 2006 12:05:00 GMT</pubDate><guid>http://www.blogjava.net/BlueDavy/archive/2006/02/24/32336.html</guid><wfw:comment>http://www.blogjava.net/BlueDavy/comments/32336.html</wfw:comment><comments>http://www.blogjava.net/BlueDavy/archive/2006/02/24/32336.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.blogjava.net/BlueDavy/comments/commentRss/32336.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/BlueDavy/services/trackbacks/32336.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 总结，就是在同一个session内如果save了一个对象，再通过session.load的方式去取这个对象取出的将仍然是当前session中的对象，也就是说不会去数据库中重新获取...<br>怎么感觉这样是不太对的，明明数据库有改变，却没有去重新的加载...&nbsp;&nbsp;<a href='http://www.blogjava.net/BlueDavy/archive/2006/02/24/32336.html'>阅读全文</a><img src ="http://www.blogjava.net/BlueDavy/aggbug/32336.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/BlueDavy/" target="_blank">BlueDavy</a> 2006-02-24 20:05 <a href="http://www.blogjava.net/BlueDavy/archive/2006/02/24/32336.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Rife的Continuations</title><link>http://www.blogjava.net/BlueDavy/archive/2006/02/16/31089.html</link><dc:creator>BlueDavy</dc:creator><author>BlueDavy</author><pubDate>Thu, 16 Feb 2006 09:31:00 GMT</pubDate><guid>http://www.blogjava.net/BlueDavy/archive/2006/02/16/31089.html</guid><wfw:comment>http://www.blogjava.net/BlueDavy/comments/31089.html</wfw:comment><comments>http://www.blogjava.net/BlueDavy/archive/2006/02/16/31089.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/BlueDavy/comments/commentRss/31089.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/BlueDavy/services/trackbacks/31089.html</trackback:ping><description><![CDATA[<P>rife作为一个full stack rapid web development framework，对它还是比较感兴趣的，今天上rife的官方网站看了下rife的features，它提供了一个关于continuations介绍的quicktime movie，不错，把continuations介绍的还是比较清晰的，虽然影片很短，^_^，但点在了点子上。<BR>一直以来我都把continuations视为我当初想做的支持页面中断的事件处理框架，但其实pageflow就是一个这样的机制，所以如果是这样的话那么continuations就显得多余了，今天看了它的quicktime movie后才明白过来，其实continuation的关注点确实不一样，比如说用户注册这个典型的程序，如果做的是服务端校验我们通常是会检测数据是否填写完备，或者用户名是否重复，如出现其中的情况，则返回到页面提示用户，当用户修改后再次提交时整个处理代码都会再执行一次，这样的处理在有些时候会很不方便的，在continuations中我们则可以直接中断返回页面，然后页面提交后将继续沿着刚刚代码的地方执行下去，就像是代码在执行过程中被中断了一下，重新获取了这部分的数据，然后继续执行，这个功能是会非常有用的，在调试中就更有用了，^_^.........<BR>Continuations的应用场景还不够突出，也许这是它现在还没流行起来的原因，^_^，其实想想有N多地方都用的着它的：<BR>在代码的执行过程中可以中断一下返回页面，重新获取所需的参数或让用户改错，^_^，爽<BR>大家来continue一下...</P><img src ="http://www.blogjava.net/BlueDavy/aggbug/31089.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/BlueDavy/" target="_blank">BlueDavy</a> 2006-02-16 17:31 <a href="http://www.blogjava.net/BlueDavy/archive/2006/02/16/31089.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>开源产品学习方法论</title><link>http://www.blogjava.net/BlueDavy/archive/2006/02/16/31059.html</link><dc:creator>BlueDavy</dc:creator><author>BlueDavy</author><pubDate>Thu, 16 Feb 2006 06:58:00 GMT</pubDate><guid>http://www.blogjava.net/BlueDavy/archive/2006/02/16/31059.html</guid><wfw:comment>http://www.blogjava.net/BlueDavy/comments/31059.html</wfw:comment><comments>http://www.blogjava.net/BlueDavy/archive/2006/02/16/31059.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/BlueDavy/comments/commentRss/31059.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/BlueDavy/services/trackbacks/31059.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Java界的开源产品多如牛毛，不掌握一定的方法论的话觉得一方面是学不来这么多的开源产品，另一方面则是根本就发挥不了开源产品的作用，一直以来我就推崇技术人员按照工具型人才--->思想型人才--->创新型人才的发展路线，所以我觉得学习和熟悉几种开源产品是必须的基本技能，但并不是说一定熟悉最新流行的开源产品，其实这个就象基于MS做开发的人员，最起码要熟悉的就是.net这些东西，只有先在熟悉这些东西的基础上才能形成更好的发展，一切都自己从底层摸起尽管会让自己学习到很多也会理解很深，但会走很多的弯路，基于开源产品能基于别人经验的基础上进行学习，这样自然会少一些弯路，而且其实这样是很容易形成自己的一些想法的。&nbsp;&nbsp;<a href='http://www.blogjava.net/BlueDavy/archive/2006/02/16/31059.html'>阅读全文</a><img src ="http://www.blogjava.net/BlueDavy/aggbug/31059.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/BlueDavy/" target="_blank">BlueDavy</a> 2006-02-16 14:58 <a href="http://www.blogjava.net/BlueDavy/archive/2006/02/16/31059.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Acegi实现对象实例级权限控制的方法</title><link>http://www.blogjava.net/BlueDavy/archive/2006/02/13/30461.html</link><dc:creator>BlueDavy</dc:creator><author>BlueDavy</author><pubDate>Mon, 13 Feb 2006 07:38:00 GMT</pubDate><guid>http://www.blogjava.net/BlueDavy/archive/2006/02/13/30461.html</guid><wfw:comment>http://www.blogjava.net/BlueDavy/comments/30461.html</wfw:comment><comments>http://www.blogjava.net/BlueDavy/archive/2006/02/13/30461.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/BlueDavy/comments/commentRss/30461.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/BlueDavy/services/trackbacks/30461.html</trackback:ping><description><![CDATA[<P>一直以来对于Acegi实现Domain Object Instance的权限控制就比较感兴趣，今天抽空大致的看了一下，感觉和我以前提出的数据权限那部分的实现是大致相同的。<BR>Acegi在Domain Object Instance上采用的是ACL的实现，ACL在实现实例级别的权限控制上确实是非常好的方法，按照ACL的思想我们很容易知道Domain Object Instance的控制需要的是user---&gt;Domain Object Instance的一个列表的维护，这点在Acegi上可以看到采用的就是通过acl_object_identity以及acl_permission这两张表来实现的，看acl_object_identity表惊喜的发现acegi也是考虑到了domain object instance的权限继承的实现的，acl_object_identity记录的是需要控制权限的domain object instance的相关信息，acl_permission记录的即为用户对于domain object instance的权限，Acegi做到的其实就是将这些通用的部分做了一个实现，在存储domain object时它帮忙做了相关的权限信息的存储，应该说acegi这样的实现确实是可以做到domain object instance的权限控制，不过感觉在acegi中要去实现对象实例级权限控制还是不那么的方便，配置起来非常的繁琐，应该基于它做一级提升，在易用性方面。<BR>而且这种做法在侵入性上仍然是无法避免的，比如需要分页获取数据时，必然是要在现在的Dao层次做一个侵入的，尽管这点经过一定的方法(Template Pattern)是可以实现无侵入性的...<BR>目前感觉在对象实例级别的权限控制上还是没有非常好的方法...<BR>曾经考虑过是否可以采用AOP的weaver来实现...<BR>还有就是在对象实例级别是否为权限控制还是业务规则定义方面是有一定的区分难度的，很多时候很难明白的去标识哪个是数据权限、哪个是业务规则，感觉在这两点上挺容易发生混淆的现象。</P><img src ="http://www.blogjava.net/BlueDavy/aggbug/30461.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/BlueDavy/" target="_blank">BlueDavy</a> 2006-02-13 15:38 <a href="http://www.blogjava.net/BlueDavy/archive/2006/02/13/30461.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>数据驱动开发框架实现简述</title><link>http://www.blogjava.net/BlueDavy/archive/2006/02/08/29906.html</link><dc:creator>BlueDavy</dc:creator><author>BlueDavy</author><pubDate>Wed, 08 Feb 2006 03:51:00 GMT</pubDate><guid>http://www.blogjava.net/BlueDavy/archive/2006/02/08/29906.html</guid><wfw:comment>http://www.blogjava.net/BlueDavy/comments/29906.html</wfw:comment><comments>http://www.blogjava.net/BlueDavy/archive/2006/02/08/29906.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/BlueDavy/comments/commentRss/29906.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/BlueDavy/services/trackbacks/29906.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 数据驱动开发框架需要提供的功能以及简要描述的实现思路。&nbsp;&nbsp;<a href='http://www.blogjava.net/BlueDavy/archive/2006/02/08/29906.html'>阅读全文</a><img src ="http://www.blogjava.net/BlueDavy/aggbug/29906.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/BlueDavy/" target="_blank">BlueDavy</a> 2006-02-08 11:51 <a href="http://www.blogjava.net/BlueDavy/archive/2006/02/08/29906.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>既然认为它是好的，就要发挥到极限－系列之三重构</title><link>http://www.blogjava.net/BlueDavy/archive/2006/01/26/29229.html</link><dc:creator>BlueDavy</dc:creator><author>BlueDavy</author><pubDate>Thu, 26 Jan 2006 02:58:00 GMT</pubDate><guid>http://www.blogjava.net/BlueDavy/archive/2006/01/26/29229.html</guid><wfw:comment>http://www.blogjava.net/BlueDavy/comments/29229.html</wfw:comment><comments>http://www.blogjava.net/BlueDavy/archive/2006/01/26/29229.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/BlueDavy/comments/commentRss/29229.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/BlueDavy/services/trackbacks/29229.html</trackback:ping><description><![CDATA[想改良一个烂设计为好设计吗？想增加或维护代码功能时更加简单吗？重构无疑是其中最好的方法之一，既然它是好的，我们就要把它发挥到极限，把重构发挥到极限的方法就像kent beck说的，采用两顶帽子的原则，工作中不断的交换帽子，^_^<BR><BR><FONT color=#008000 size=4><STRONG>重构的好处</STRONG></FONT><BR>1、改良设计<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 设计在一开始不可能做的很完善、很完美，只能是通过在开发的过程不断的去改良和完善，重构就是最好的方法之一，通过重构可将设计快速的改良。<BR>2、增加或维护代码功能时更加的简单<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 重构进行的原因主要还是因为在增加或维护代码时进行的很困难，这个时候重构原有代码就是为了让增加或维护代码功能变得更为的简单。<BR><BR><FONT color=#008000 size=4><STRONG>重构的实现</STRONG></FONT><BR>重构并不是什么新思想、新技术或者新方法，是一个50年代就已经有N多人融入他们的开发中形成习惯的过程，那么重构到底应该怎么去做呢？在这点上我觉得我没有什么多发言的意义，建议大家参考《重构》一书，书中阐述了很多优秀的编码习惯以及重构进行的场合、方法，重构不象设计模式，重构应该被形成习惯融入到开发中去，重构不是一项独立的任务。<BR>重构依赖于良好的测试体系，如之前讲过的单元测试的贯彻。<BR>Java的开发人员更是可以借助IDE来快速的完成重构的工作。<BR><BR><FONT color=#008000 size=4><STRONG>经验总结</STRONG></FONT><BR>慢慢的重构也变成了我的开发习惯，重构保证了简单设计的可行，同时也保证了软件的质量。<BR>有了重构，我在开发中就可以实行”不要求高质量的实现代码，但要求高质量的测试代码“，高质量的实现代码在任务完成时即可通过重构的技术去进行，就像我以前一篇blog提及过的一样，我在代码实现过程采用的就是：<BR>1、编写能够满足测试的代码。<BR>2、对代码进行重构。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.1&nbsp;按照《重构》的一些模式进行<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.2 OO<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.3 设计模式<BR><img src ="http://www.blogjava.net/BlueDavy/aggbug/29229.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/BlueDavy/" target="_blank">BlueDavy</a> 2006-01-26 10:58 <a href="http://www.blogjava.net/BlueDavy/archive/2006/01/26/29229.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>既然认为它是好的，就要发挥到极限－系列之二单元测试</title><link>http://www.blogjava.net/BlueDavy/archive/2006/01/22/28976.html</link><dc:creator>BlueDavy</dc:creator><author>BlueDavy</author><pubDate>Sun, 22 Jan 2006 15:43:00 GMT</pubDate><guid>http://www.blogjava.net/BlueDavy/archive/2006/01/22/28976.html</guid><wfw:comment>http://www.blogjava.net/BlueDavy/comments/28976.html</wfw:comment><comments>http://www.blogjava.net/BlueDavy/archive/2006/01/22/28976.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/BlueDavy/comments/commentRss/28976.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/BlueDavy/services/trackbacks/28976.html</trackback:ping><description><![CDATA[既然测试是好的，那就把它发挥到极限。<BR>测试是好的，这一点无可厚非，几乎做软件的人都是认可的，本篇只是谈谈测试中的单元测试部分，单元测试的目的是为了保证类中的方法是符合设计时的需求的，需求驱动似的类实现，^_^<BR><BR><FONT color=#008000 size=4><STRONG>单元测试的好处<BR></STRONG></FONT>1、保证类对于设计以及需求的符合<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在没有单元测试的情况下，其实是很难保证类对于设计以及需求的符合的，很多情况往往会因为开发人员本身的因素将实现代码复杂化，并且编写出很多设计和需求根本不需要的东西。<BR>2、降低调试的复杂性<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 想想在没有单元测试的情况下，调试通常是集成时才做的，这个时候要通过慢慢的跟踪来查找问题的原因，而在web系统中就更痛苦了，总是要重启，如果不想那么痛苦，就采用单元测试吧。<BR>3、减少集成时出错的机率<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;单元测试可保证暴露给外部的API的正确性，减少要通过集成才发现错误的现象。<BR>4、保证重构和简单设计的可行<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 想想，如果没有单元测试，怎么敢对代码做重构呢，如果没有单元测试，简单设计很难通过重构去演变成为将来更好的设计。<BR><BR><STRONG><FONT color=#008000 size=4>单元测试的实现</FONT></STRONG><BR>单元测试的实现采取的方法通常是xUnit，在Java界就是junit了，最重要的仍然不是工具，而是怎么去实现单元测试的方法，测试驱动开发无疑是最佳的编写测试的方法，首先根据设计或需求编写测试，根据测试编写代码，直到测试通过为止。<BR>在代码出现bug时，一定要先把出现bug的情况补充到测试中去，接下来仍然是修改实现代码，直到测试通过。<BR>单元测试编写的原则其实很简单，就是测试一定情况下类的执行是否符合预期。<BR>还是举例来说：<BR>假设需要编写一个根据用户名和密码验证用户的服务，按照TDD我们首先编写单元测试类，我们应该怎么来编写这个单元测试类呢，一般可按照一个这样的步骤：<BR>1、分析类的输入。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这点通常是分析类依赖外部什么类，需要在测试类中提前注入。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 以上面的服务来说，通常需要依赖的是用户的Dao类。<BR>2、分析方法的输入造成的输出的影响。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这点通常是分析方法输入的参数对执行结果造成的影响。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 以上面的服务来说，输入的参数为用户名和密码，这个时候会有几种情况会出现：<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.1 用户名或密码为null<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在这种情况下，假设期待的输出为false<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.2 用户名和密码都为null<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在这种情况下，假设期待的输出为false<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.3&nbsp;输入的用户名和密码在系统中存在<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在这种情况下，假设期待的输出为true<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.4 用户名或密码其中一项输入不正确，验证不通过<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在这种情况下，假设期待的抛出AuthronizedException<BR>在经过这样的分析后，就可以开始编写测试类了，编写的测试类如下(示例代码而已)：<BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><IMG id=Codehighlighter1_46_1309_Open_Image onclick="this.style.display='none'; Codehighlighter1_46_1309_Open_Text.style.display='none'; Codehighlighter1_46_1309_Closed_Image.style.display='inline'; Codehighlighter1_46_1309_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_46_1309_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_46_1309_Closed_Text.style.display='none'; Codehighlighter1_46_1309_Open_Image.style.display='inline'; Codehighlighter1_46_1309_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align=top><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;UserServiceTest&nbsp;</SPAN><SPAN style="COLOR: #0000ff">extends</SPAN><SPAN style="COLOR: #000000">&nbsp;TestCase&nbsp;</SPAN><SPAN id=Codehighlighter1_46_1309_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_46_1309_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">private</SPAN><SPAN style="COLOR: #000000">&nbsp;UserDao&nbsp;dao</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #0000ff">null</SPAN><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">private</SPAN><SPAN style="COLOR: #000000">&nbsp;UserService&nbsp;service</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #0000ff">null</SPAN><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">private</SPAN><SPAN style="COLOR: #000000">&nbsp;User&nbsp;user</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #0000ff">null</SPAN><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;<BR><IMG id=Codehighlighter1_203_269_Open_Image onclick="this.style.display='none'; Codehighlighter1_203_269_Open_Text.style.display='none'; Codehighlighter1_203_269_Closed_Image.style.display='inline'; Codehighlighter1_203_269_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_203_269_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_203_269_Closed_Text.style.display='none'; Codehighlighter1_203_269_Open_Image.style.display='inline'; Codehighlighter1_203_269_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">static</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;main(String[]&nbsp;args)&nbsp;</SPAN><SPAN id=Codehighlighter1_203_269_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_203_269_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;junit.textui.TestRunner.run(UserServiceTest.</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top><BR><IMG id=Codehighlighter1_316_563_Open_Image onclick="this.style.display='none'; Codehighlighter1_316_563_Open_Text.style.display='none'; Codehighlighter1_316_563_Closed_Image.style.display='inline'; Codehighlighter1_316_563_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_316_563_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_316_563_Closed_Text.style.display='none'; Codehighlighter1_316_563_Open_Image.style.display='inline'; Codehighlighter1_316_563_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">protected</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;setUp()&nbsp;</SPAN><SPAN style="COLOR: #0000ff">throws</SPAN><SPAN style="COLOR: #000000">&nbsp;Exception&nbsp;</SPAN><SPAN id=Codehighlighter1_316_563_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_316_563_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">super</SPAN><SPAN style="COLOR: #000000">.setUp();<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dao</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;UserDaoImpl();<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;user</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;User();<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;user.setName(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">TEST_BLUEDAVY</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;user.setPass(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">JERRY</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dao.save(user);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;service</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;UserServiceImpl();<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;service.setDao(dao);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top><BR><IMG id=Codehighlighter1_613_671_Open_Image onclick="this.style.display='none'; Codehighlighter1_613_671_Open_Text.style.display='none'; Codehighlighter1_613_671_Closed_Image.style.display='inline'; Codehighlighter1_613_671_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_613_671_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_613_671_Closed_Text.style.display='none'; Codehighlighter1_613_671_Open_Image.style.display='inline'; Codehighlighter1_613_671_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">protected</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;tearDown()&nbsp;</SPAN><SPAN style="COLOR: #0000ff">throws</SPAN><SPAN style="COLOR: #000000">&nbsp;Exception&nbsp;</SPAN><SPAN id=Codehighlighter1_613_671_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_613_671_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">super</SPAN><SPAN style="COLOR: #000000">.tearDown();<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dao.delete(user);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;<BR><IMG id=Codehighlighter1_722_802_Open_Image onclick="this.style.display='none'; Codehighlighter1_722_802_Open_Text.style.display='none'; Codehighlighter1_722_802_Closed_Image.style.display='inline'; Codehighlighter1_722_802_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_722_802_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_722_802_Closed_Text.style.display='none'; Codehighlighter1_722_802_Open_Image.style.display='inline'; Codehighlighter1_722_802_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;testWhenNameAndPassAreNull()</SPAN><SPAN id=Codehighlighter1_722_802_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_722_802_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(</SPAN><SPAN style="COLOR: #0000ff">false</SPAN><SPAN style="COLOR: #000000">,service.login(user.getName(),user.getPass()));<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top><BR><IMG id=Codehighlighter1_847_927_Open_Image onclick="this.style.display='none'; Codehighlighter1_847_927_Open_Text.style.display='none'; Codehighlighter1_847_927_Closed_Image.style.display='inline'; Codehighlighter1_847_927_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_847_927_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_847_927_Closed_Text.style.display='none'; Codehighlighter1_847_927_Open_Image.style.display='inline'; Codehighlighter1_847_927_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;testWhenNameOrPassIsNull()</SPAN><SPAN id=Codehighlighter1_847_927_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_847_927_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(</SPAN><SPAN style="COLOR: #0000ff">false</SPAN><SPAN style="COLOR: #000000">,service.login(user.getName(),user.getPass()));<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;<BR><IMG id=Codehighlighter1_981_1060_Open_Image onclick="this.style.display='none'; Codehighlighter1_981_1060_Open_Text.style.display='none'; Codehighlighter1_981_1060_Closed_Image.style.display='inline'; Codehighlighter1_981_1060_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_981_1060_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_981_1060_Closed_Text.style.display='none'; Codehighlighter1_981_1060_Open_Image.style.display='inline'; Codehighlighter1_981_1060_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;testWhenNameAndPassAreCorrect()</SPAN><SPAN id=Codehighlighter1_981_1060_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_981_1060_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(</SPAN><SPAN style="COLOR: #0000ff">true</SPAN><SPAN style="COLOR: #000000">,service.login(user.getName(),user.getPass()));<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;<BR><IMG id=Codehighlighter1_1110_1302_Open_Image onclick="this.style.display='none'; Codehighlighter1_1110_1302_Open_Text.style.display='none'; Codehighlighter1_1110_1302_Closed_Image.style.display='inline'; Codehighlighter1_1110_1302_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_1110_1302_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_1110_1302_Closed_Text.style.display='none'; Codehighlighter1_1110_1302_Open_Image.style.display='inline'; Codehighlighter1_1110_1302_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;testWhenNameOrPassIsError()</SPAN><SPAN id=Codehighlighter1_1110_1302_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_1110_1302_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG id=Codehighlighter1_1123_1191_Open_Image onclick="this.style.display='none'; Codehighlighter1_1123_1191_Open_Text.style.display='none'; Codehighlighter1_1123_1191_Closed_Image.style.display='inline'; Codehighlighter1_1123_1191_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_1123_1191_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_1123_1191_Closed_Text.style.display='none'; Codehighlighter1_1123_1191_Open_Image.style.display='inline'; Codehighlighter1_1123_1191_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">try</SPAN><SPAN id=Codehighlighter1_1123_1191_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_1123_1191_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;service.login(user.getName(),user.getPass());<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG id=Codehighlighter1_1219_1296_Open_Image onclick="this.style.display='none'; Codehighlighter1_1219_1296_Open_Text.style.display='none'; Codehighlighter1_1219_1296_Closed_Image.style.display='inline'; Codehighlighter1_1219_1296_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_1219_1296_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_1219_1296_Closed_Text.style.display='none'; Codehighlighter1_1219_1296_Open_Image.style.display='inline'; Codehighlighter1_1219_1296_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">catch</SPAN><SPAN style="COLOR: #000000">(Exception&nbsp;e)</SPAN><SPAN id=Codehighlighter1_1219_1296_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_1219_1296_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(AuthronizedException.</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">,e.getClass());<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</SPAN></SPAN></DIV><BR>在编写完测试类后就可以开始编写实现代码了，实现代码在编写的时候很简单，只要能够保证测试通过就完事，在测试通过后可以开始考虑重构的事，重构仍然只要保证测试通过即可，其实这个时候就可以看到，简单设计就变得可行了，因为可以通过重构来提升设计。<BR>如果将来这段代码出现bug，就把bug中的输入情况也编写为一个测试方法进行测试，开始运行就应该和bug一样出现问题，这时只需去修正实现代码，直到测试通过为止，那么bug也就自然被修正了。<BR>简单的单元测试的编写较为简单，复杂的单元测试则可能需要使用Mock来模拟一些环境，Mock方面的工具有很多，大家可以去参考相关的开源工具的网站。&nbsp;&nbsp;&nbsp;&nbsp; <BR><BR><FONT color=#008000 size=4><STRONG>经验总结</STRONG></FONT><BR>对于单元测试通常很多人都有疑问，执行起来的时候经常是不够彻底，特别是在项目时间紧张的情况下，总是觉得编写测试是一种耽误时间的事，其实编写单元测试会为你节省非常多的时间，想想我们大部分的项目都是在集成、修改bug和维护上消耗了大量的时间，既然单元测试这么好，那么我们就实现单元测试吧。<BR>在单元测试中最重要的注意点就是不要依赖于正常的运行数据，所有的数据都要通过代码模拟出来，在测试完毕后清除，避免造成测试对于运行数据的依赖，同时也避免测试数据对于实际运行系统的影响。<BR><img src ="http://www.blogjava.net/BlueDavy/aggbug/28976.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/BlueDavy/" target="_blank">BlueDavy</a> 2006-01-22 23:43 <a href="http://www.blogjava.net/BlueDavy/archive/2006/01/22/28976.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>需要html元素标签吗？</title><link>http://www.blogjava.net/BlueDavy/archive/2006/01/14/28047.html</link><dc:creator>BlueDavy</dc:creator><author>BlueDavy</author><pubDate>Sat, 14 Jan 2006 11:43:00 GMT</pubDate><guid>http://www.blogjava.net/BlueDavy/archive/2006/01/14/28047.html</guid><wfw:comment>http://www.blogjava.net/BlueDavy/comments/28047.html</wfw:comment><comments>http://www.blogjava.net/BlueDavy/archive/2006/01/14/28047.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/BlueDavy/comments/commentRss/28047.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/BlueDavy/services/trackbacks/28047.html</trackback:ping><description><![CDATA[在很多的web框架中，经常会看到提供html元素的标签，例如在采用velocity作为显示层的很多web框架中就会提供诸如table、input等这些元素标签，提供这些标签的用意是很清楚的，就是为了能够统一整个web应用的显示形式和操作模式，但这些标签的提供却在很大程度上给UI集成带来了麻烦，想想本来只要UI设计师切割图片然后直接导为html的部分，变成了还需要开发人员去把页面所有的元素改为使用标签的方式，平白无故的增加了痛苦。<BR>但从其出发点上去讲，仍然是好的，必须有一种有效的统一整个web应用的显示形式和操作模式的解决方案，个人觉得用css结合纯的html元素来实现统一的显示形式的控制是种不错的解决方案，而统一的操作模式则可借助统一的js来实现。<BR>通常提供这些标签的框架则带来了另外一个好处，就是会同时提供一些扩展的元素标签，就象树标签、tab页标签、容器标签等等，这些是很有必要也是值得提供的，这是能减少UI集成的工作量的事，作为web框架自然是要多从使用、维护的方便性上去考虑，还是保留现在html的纯洁性，^_^，在其基础上提供出象tree、tab这样的html标签。<img src ="http://www.blogjava.net/BlueDavy/aggbug/28047.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/BlueDavy/" target="_blank">BlueDavy</a> 2006-01-14 19:43 <a href="http://www.blogjava.net/BlueDavy/archive/2006/01/14/28047.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>1M内存可用来缓存多少对象？</title><link>http://www.blogjava.net/BlueDavy/archive/2006/01/12/27831.html</link><dc:creator>BlueDavy</dc:creator><author>BlueDavy</author><pubDate>Thu, 12 Jan 2006 15:57:00 GMT</pubDate><guid>http://www.blogjava.net/BlueDavy/archive/2006/01/12/27831.html</guid><wfw:comment>http://www.blogjava.net/BlueDavy/comments/27831.html</wfw:comment><comments>http://www.blogjava.net/BlueDavy/archive/2006/01/12/27831.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.blogjava.net/BlueDavy/comments/commentRss/27831.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/BlueDavy/services/trackbacks/27831.html</trackback:ping><description><![CDATA[为了提高系统的响应性能，一般都会采用缓存技术来实现，如果用象ehcache、oscache这样的开源的cache工具来实现，一般都需要由开发人员来设置maxElementsInMemory这个值，但这个值在设置的时候大家都是怎么去设置的呢？凭想像还是随便写一个值呢？这个值设的过大嘛有可能会造成outofmemory，设的过小嘛又浪费服务器巨大的内存，为了能够更好的设置这个值，我写了个测试程序来估算1M内存能够缓存多少个对象，代码如下：<BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><IMG id=Codehighlighter1_23_1365_Open_Image onclick="this.style.display='none'; Codehighlighter1_23_1365_Open_Text.style.display='none'; Codehighlighter1_23_1365_Closed_Image.style.display='inline'; Codehighlighter1_23_1365_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_23_1365_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_23_1365_Closed_Text.style.display='none'; Codehighlighter1_23_1365_Open_Image.style.display='inline'; Codehighlighter1_23_1365_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align=top><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;testSpike()</SPAN><SPAN id=Codehighlighter1_23_1365_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_23_1365_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">最大的内存为：</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">Runtime.getRuntime().maxMemory()</SPAN><SPAN style="COLOR: #000000">/</SPAN><SPAN style="COLOR: #000000">1024</SPAN><SPAN style="COLOR: #000000">);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">总的内存为：</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">Runtime.getRuntime().totalMemory()</SPAN><SPAN style="COLOR: #000000">/</SPAN><SPAN style="COLOR: #000000">1024</SPAN><SPAN style="COLOR: #000000">);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">==================================</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">long</SPAN><SPAN style="COLOR: #000000">&nbsp;currMemory</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">Runtime.getRuntime().freeMemory();<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">目前可用的内存为：</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">currMemory</SPAN><SPAN style="COLOR: #000000">/</SPAN><SPAN style="COLOR: #000000">1024</SPAN><SPAN style="COLOR: #000000">);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">==================================</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Map&nbsp;cache</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;HashMap();<BR><IMG id=Codehighlighter1_437_884_Open_Image onclick="this.style.display='none'; Codehighlighter1_437_884_Open_Text.style.display='none'; Codehighlighter1_437_884_Closed_Image.style.display='inline'; Codehighlighter1_437_884_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_437_884_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_437_884_Closed_Text.style.display='none'; Codehighlighter1_437_884_Open_Image.style.display='inline'; Codehighlighter1_437_884_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">for</SPAN><SPAN style="COLOR: #000000">&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;i&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;&nbsp;i&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">500000</SPAN><SPAN style="COLOR: #000000">;&nbsp;i</SPAN><SPAN style="COLOR: #000000">++</SPAN><SPAN style="COLOR: #000000">)&nbsp;</SPAN><SPAN id=Codehighlighter1_437_884_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_437_884_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MockBean&nbsp;bean</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;MockBean();<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bean.setId(i);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bean.setName(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">jerry</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">i);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bean.setValue(i</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">jerry</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cache.put(String.valueOf(i),&nbsp;bean);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">long</SPAN><SPAN style="COLOR: #000000">&nbsp;tempMemory</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">Runtime.getRuntime().freeMemory();<BR><IMG id=Codehighlighter1_744_874_Open_Image onclick="this.style.display='none'; Codehighlighter1_744_874_Open_Text.style.display='none'; Codehighlighter1_744_874_Closed_Image.style.display='inline'; Codehighlighter1_744_874_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_744_874_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_744_874_Closed_Text.style.display='none'; Codehighlighter1_744_874_Open_Image.style.display='inline'; Codehighlighter1_744_874_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">((currMemory</SPAN><SPAN style="COLOR: #000000">-</SPAN><SPAN style="COLOR: #000000">tempMemory)</SPAN><SPAN style="COLOR: #000000">/</SPAN><SPAN style="COLOR: #000000">1024</SPAN><SPAN style="COLOR: #000000">==</SPAN><SPAN style="COLOR: #000000">1024</SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN id=Codehighlighter1_744_874_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_744_874_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">此时可用的内存为：</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">tempMemory</SPAN><SPAN style="COLOR: #000000">/</SPAN><SPAN style="COLOR: #000000">1024</SPAN><SPAN style="COLOR: #000000">);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">此时缓存了：</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">i</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">个对象</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">break</SPAN><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">==================================</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cache.clear();<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">long</SPAN><SPAN style="COLOR: #000000">&nbsp;tempMemory</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">Runtime.getRuntime().freeMemory();<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">目前可用的内存为：</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">tempMemory</SPAN><SPAN style="COLOR: #000000">/</SPAN><SPAN style="COLOR: #000000">1024</SPAN><SPAN style="COLOR: #000000">);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">消耗的内存为：</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">(currMemory</SPAN><SPAN style="COLOR: #000000">-</SPAN><SPAN style="COLOR: #000000">tempMemory)</SPAN><SPAN style="COLOR: #000000">/</SPAN><SPAN style="COLOR: #000000">1024</SPAN><SPAN style="COLOR: #000000">);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">==================================</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Runtime.getRuntime().gc();<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tempMemory</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">Runtime.getRuntime().freeMemory();<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">目前可用的内存为：</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">tempMemory</SPAN><SPAN style="COLOR: #000000">/</SPAN><SPAN style="COLOR: #000000">1024</SPAN><SPAN style="COLOR: #000000">);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">消耗的内存为：</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">(currMemory</SPAN><SPAN style="COLOR: #000000">-</SPAN><SPAN style="COLOR: #000000">tempMemory)</SPAN><SPAN style="COLOR: #000000">/</SPAN><SPAN style="COLOR: #000000">1024</SPAN><SPAN style="COLOR: #000000">);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;<BR><IMG id=Codehighlighter1_1406_1445_Open_Image onclick="this.style.display='none'; Codehighlighter1_1406_1445_Open_Text.style.display='none'; Codehighlighter1_1406_1445_Closed_Image.style.display='inline'; Codehighlighter1_1406_1445_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_1406_1445_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_1406_1445_Closed_Text.style.display='none'; Codehighlighter1_1406_1445_Open_Image.style.display='inline'; Codehighlighter1_1406_1445_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">private</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;print(String&nbsp;msg)</SPAN><SPAN id=Codehighlighter1_1406_1445_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN><SPAN id=Codehighlighter1_1406_1445_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(msg);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN></DIV><BR>在我机器上运行的结果是1M内存可缓存大概4479个对象，同时可以看到，在cache.clear后内存并没有变化，因为gc是没那么及时的，这个时候显式的调用gc则会发现可用的内存量甚至比最初都多，呵呵<BR>当然，这里只是个简单的测试，这里测试的也只是缓存一个非常简单的bean对象，缓存的对象消耗的内存大小还需要根据这个对象中具体的内容而定，比如当缓存的是blob类型的字段的时候，可想而知，这个时候消耗的内存量绝对是不同的。<BR>这里只是建议大家在对系统性能做优化时最好根据需要缓存的内容做一个估算，设置好应用所需要的jvm的内存值，以便充分利用服务器的硬件资源。<img src ="http://www.blogjava.net/BlueDavy/aggbug/27831.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/BlueDavy/" target="_blank">BlueDavy</a> 2006-01-12 23:57 <a href="http://www.blogjava.net/BlueDavy/archive/2006/01/12/27831.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>