﻿<?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-Study &amp; Summary </title><link>http://www.blogjava.net/wfeng007/</link><description /><language>zh-cn</language><lastBuildDate>Tue, 28 Apr 2026 14:30:36 GMT</lastBuildDate><pubDate>Tue, 28 Apr 2026 14:30:36 GMT</pubDate><ttl>60</ttl><item><title>[导入]PooledExecutor 研究(第三方包,当时还没有用jdk5)</title><link>http://www.blogjava.net/wfeng007/archive/2008/10/12/266826.html</link><dc:creator>wfeng007</dc:creator><author>wfeng007</author><pubDate>Sun, 12 Oct 2008 12:35:00 GMT</pubDate><guid>http://www.blogjava.net/wfeng007/archive/2008/10/12/266826.html</guid><wfw:comment>http://www.blogjava.net/wfeng007/comments/266826.html</wfw:comment><comments>http://www.blogjava.net/wfeng007/archive/2008/10/12/266826.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wfeng007/comments/commentRss/266826.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wfeng007/services/trackbacks/266826.html</trackback:ping><description><![CDATA[以前记的笔记。<img src ="http://blog.csdn.net/wfeng007/aggbug/3062787.aspx" width = "1" height = "1" /><br>文章来源:<a href='http://blog.csdn.net/wfeng007/archive/2008/10/12/3062787.aspx'>http://blog.csdn.net/wfeng007/archive/2008/10/12/3062787.aspx</a><img src ="http://www.blogjava.net/wfeng007/aggbug/266826.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wfeng007/" target="_blank">wfeng007</a> 2008-10-12 20:35 <a href="http://www.blogjava.net/wfeng007/archive/2008/10/12/266826.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>httpComponents 果然不俗</title><link>http://www.blogjava.net/wfeng007/archive/2008/05/18/201283.html</link><dc:creator>wfeng007</dc:creator><author>wfeng007</author><pubDate>Sun, 18 May 2008 10:42:00 GMT</pubDate><guid>http://www.blogjava.net/wfeng007/archive/2008/05/18/201283.html</guid><wfw:comment>http://www.blogjava.net/wfeng007/comments/201283.html</wfw:comment><comments>http://www.blogjava.net/wfeng007/archive/2008/05/18/201283.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wfeng007/comments/commentRss/201283.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wfeng007/services/trackbacks/201283.html</trackback:ping><description><![CDATA[<br />
httpComponents 似乎是原先 apache commons HttpClient 重构的项目。<br />
这个项目中除了原先作为 httpClient的项目之外还有一个http底层实现HttpCore项目。<br />
本来在写一个tcp/ip 服务器程序时想找一个http message解析器的没想到找到了 HttpComponents。<br />
虽然刚刚beta1版本，但是其代码确实比较经典。<br />
<br />
分析其协议底层代码（主要是nio）,对io部分还进行了通用型的封装。比如EnpandableByteBuffer CharArrayBuffer等等。<br />
粗略了看了一下nio通信部分的实现，也是那种比较经典的模式。<br />
从作者对继承与实现的使用也很清晰，感觉应该是经过长时间整理分析的结果。<br />
而HttpMessage族作为http消息包的结构分解也基本符合rfc1945 rfc2116。<br />
总之值得整体研究一番，学习nio、（http）协议实现、甚至java基本语法使用的好教材。<br />
<br />
<br />
<br />
<br />
<br />
<img src ="http://www.blogjava.net/wfeng007/aggbug/201283.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wfeng007/" target="_blank">wfeng007</a> 2008-05-18 18:42 <a href="http://www.blogjava.net/wfeng007/archive/2008/05/18/201283.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java NIO: selector 机制分析</title><link>http://www.blogjava.net/wfeng007/archive/2008/04/06/191112.html</link><dc:creator>wfeng007</dc:creator><author>wfeng007</author><pubDate>Sun, 06 Apr 2008 13:03:00 GMT</pubDate><guid>http://www.blogjava.net/wfeng007/archive/2008/04/06/191112.html</guid><wfw:comment>http://www.blogjava.net/wfeng007/comments/191112.html</wfw:comment><comments>http://www.blogjava.net/wfeng007/archive/2008/04/06/191112.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/wfeng007/comments/commentRss/191112.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wfeng007/services/trackbacks/191112.html</trackback:ping><description><![CDATA[<br />
在学习IBM的那个NIO教程时发现，异步IO这部分的代码居然有个严重问题。<br />
即client突然中断 tcp连接时。服务端会进入一个令人崩溃的无限循环。<br />
<br />
后来发现其实是因为selector在tcp连接已经断开时，还是能够select()出OP_READ状态的SocketChannel的SelectedKey。<br />
这时需要通过Channel读取数据到buffer的过程时的返回值来判断。<br />
这个反回值其实就是读取的字节数。该数字为0时说明就是一般的没有数据可读取，而当为-1时其实表示底层tcp已经断开了。(但IE的连接有点不同,read时直接给出Exception,反正这些情况都要判断了.)<br />
<br />
<br />
之后又想到，那如何注销selector与SocketChannel之间的关联呢？selector内部基本的运作是怎么样的呢？ javadoc中写的是key.cancel()方法。socket的close()在windows似乎也有一样的功能。<br />
<br />
<br />
这里可以用两张图来表示。<br />
<br />
<img alt="" src="http://www.blogjava.net/images/blogjava_net/wfeng007/DSC00693.JPG" height="800" width="600" /><br />
<br />
<img alt="" src="http://www.blogjava.net/images/blogjava_net/wfeng007/DSC00698.JPG" height="800" width="600" /><br />
<img src ="http://www.blogjava.net/wfeng007/aggbug/191112.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wfeng007/" target="_blank">wfeng007</a> 2008-04-06 21:03 <a href="http://www.blogjava.net/wfeng007/archive/2008/04/06/191112.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>再读“向依赖关系宣战”后的一些质疑。。。</title><link>http://www.blogjava.net/wfeng007/archive/2008/03/17/186765.html</link><dc:creator>wfeng007</dc:creator><author>wfeng007</author><pubDate>Mon, 17 Mar 2008 07:14:00 GMT</pubDate><guid>http://www.blogjava.net/wfeng007/archive/2008/03/17/186765.html</guid><wfw:comment>http://www.blogjava.net/wfeng007/comments/186765.html</wfw:comment><comments>http://www.blogjava.net/wfeng007/archive/2008/03/17/186765.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wfeng007/comments/commentRss/186765.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wfeng007/services/trackbacks/186765.html</trackback:ping><description><![CDATA[<br />
最早看到&#8220;向依赖关系宣战&#8221;这篇文章是在《程序员》杂志上的。当时流行讨论ioc di等概念，这篇文章一出，似乎已经将这些混乱的东西讲清楚了。我就是从这篇文章开始理解IoC阿、DI的概念的。<br />
<br />
现在看来这篇文章确实比较详细，但是反复看的话似乎感觉比较罗嗦。而且通过这两年的实践过后，我发现其实这几个概念在描述时还是有偏差的。<br />
下面有些质疑之处：<br />
1。 IoC与DI，马丁同学提出的依赖注入。。这个名词表面上怎么看都和控制反转扯不上关系。但是他又说&#8220;。。。。应该叫DI&#8221;。结果所有人就把DI与IoC等同，甚至就把DI当作IoC的一个别名来用。。。<br />
我到感觉DI与IoC是指同以概念的不同方面。DI强调的是&#8220;依赖的形成&#8221;即，框架或容器如何得到需要运行的&#8220;实现（implements）&#8221;的。而IoC本身概念是强调整体主控权与&#8220;库&#8221;调用方式相反。即由框架或容器主导主控权。或者说依赖于控制权相反。<br />
<br />
2。IoC与依赖倒置。<br />
文中似乎没有就两者关系进行详细说明。<br />
个人感觉IoC其实就是以依赖倒置为基础的。IoC是在特定环境中的DI特例，并且关注到了&#8220;实现&#8221;与&#8220;使用者&#8221;依赖关系产生的问题，（因为事实上调用时还是存在依赖关系的。）所以需要有&#8220;注册&#8221;这个过程。但是IoC并没有强调&#8220;注册&#8221;。<br />
<img src ="http://www.blogjava.net/wfeng007/aggbug/186765.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wfeng007/" target="_blank">wfeng007</a> 2008-03-17 15:14 <a href="http://www.blogjava.net/wfeng007/archive/2008/03/17/186765.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>测试一下 导入功能</title><link>http://www.blogjava.net/wfeng007/archive/2008/01/18/176233.html</link><dc:creator>wfeng007</dc:creator><author>wfeng007</author><pubDate>Fri, 18 Jan 2008 07:36:00 GMT</pubDate><guid>http://www.blogjava.net/wfeng007/archive/2008/01/18/176233.html</guid><wfw:comment>http://www.blogjava.net/wfeng007/comments/176233.html</wfw:comment><comments>http://www.blogjava.net/wfeng007/archive/2008/01/18/176233.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wfeng007/comments/commentRss/176233.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wfeng007/services/trackbacks/176233.html</trackback:ping><description><![CDATA[测试一下 导入功能<br />
<img src ="http://www.blogjava.net/wfeng007/aggbug/176233.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wfeng007/" target="_blank">wfeng007</a> 2008-01-18 15:36 <a href="http://www.blogjava.net/wfeng007/archive/2008/01/18/176233.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转载]Use Story方法</title><link>http://www.blogjava.net/wfeng007/archive/2006/04/03/38860.html</link><dc:creator>wfeng007</dc:creator><author>wfeng007</author><pubDate>Mon, 03 Apr 2006 03:24:00 GMT</pubDate><guid>http://www.blogjava.net/wfeng007/archive/2006/04/03/38860.html</guid><wfw:comment>http://www.blogjava.net/wfeng007/comments/38860.html</wfw:comment><comments>http://www.blogjava.net/wfeng007/archive/2006/04/03/38860.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wfeng007/comments/commentRss/38860.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wfeng007/services/trackbacks/38860.html</trackback:ping><description><![CDATA[
		<font size="2">最近在参与一个棘手项目，居然直接参与到需求阶段了。 虽然，目标是架构师不过，分析师的活看来也是要会的。网上找到一篇(好像也是唯一一篇)讲述use stories的文章。拿来借鉴一下吧。。。。<br /><br />出处：Extreme Programming 论坛</font>
		<br />
		<font size="2">作者：light</font>
		<font size="2">
				<font>
						<br />
				</font>
		</font>
		<p>
		</p>
		<p>
				<font size="2">
						<font>
								<font face="Times New Roman">胡乱说说，里面肯定存在着不少的错误，还请高手指正。 </font>
						</font>
				</font>
		</p>
		<p>
				<font size="2">
						<font>
								<font face="Times New Roman">Use
Stories就是系统要实现的功能。它表述起来非常的简单，一个Use
Stories只需要几句话就可以写完。之所以这样是因为用户需求的细节是非常易变的，而其高层描述却是相对稳定的。所以我们可以通过使用Use
Stories的方法来从高层确定需要开发的内容，这些单纯的Use Story相当于系统中可能的点，而由我们通过与用户交流所得到的所有Use
Stories则构成了一个面，它就是整个系统所需要实现的功能。 </font>
						</font>
				</font>
		</p>
		<p>
				<font size="2">
						<font>
								<font face="Times New Roman">深入思考上面这段话的含义就会发现Use
Stories在整个项目的初始分析阶段起的作用只是一个占位附。他告诉我们这样功能在实作的时候应该要实现，但是具体需要实现什么，怎么实现则是在迭代
过程中的分析阶段所需要的事情。所以在写Use Stories的时候请切记，一定要简单概括，不可明确描述实现细节方面的问题。 </font>
						</font>
				</font>
		</p>
		<p>
				<font size="2">
						<font>
								<font face="Times New Roman">说到这里就不能不说一下Use
Story与Use Case的关系，我个人认为Use
Story是一个更高层的分析阶段，它的抽象层次非常的高，如前面所说，它是一个占位符，而在具体对一个Use
Story进行分析的时候则可以使用Use Case分析技术，将一个Use Story分解成为若干个Use
Case。当然上面这段描述的前提是需要开发的系统足够的大Use Story对相对较大，一个Use Story可以折分一系列Use
Case。但是如果项目的规则相对较小，那么可以直接使用Use Case来取代Use
Story，这个在开发的时候需要灵活的掌握，不可死板追求到底用Use Story还是Use Case。 </font>
						</font>
				</font>
		</p>
		<p>
				<font size="2">
						<font>
								<font face="Times New Roman">Use
Story中除了包含对功能的简单描述之外，还可以酌情加入对异常情况的描述。虽然在具体分析一个Use
Story的时候还需要将其异常情况进行详细的列出，但是在撰写Use
Story的时候还是有必要的尽可能的将它们列出，其原因在于，对异常情况的描述可以帮助我们发现一些在正常情况下无法体现出来的Use
Story之间的关系。这对我们撰写Use
Story的描述部分是有一定的帮助的，另外也可以在这个初始阶段提出一些问题，然后等待进入具体迭代的分析阶段时再进行解答。 </font>
						</font>
				</font>
		</p>
		<p>
				<font size="2">
						<font>
								<font face="Times New Roman">Use
Story内的描述只是开发者系统的一个最初步认识，所以以后开发者在实际开发时参考这些Use
Story时一定要持着一种怀疑态度，再重复一次Use
Story只是对高层系统一部分的抽象度非常高的描述。用户在具体开发的时候应该维护一份Use Story列表，如果在实际开发一个Use
Story（或者这个Use Story所对应的某一个Use Case）的时候，遇到了对其它Use Story有影响的问题应该在这份Use
Story列表当中标出。以便我们在这些受影响功能进行分析的时候可以尽量多的认识到这些影响它的问题。  </font>
						</font>
				</font>
		</p>
		<p>
				<font size="2">
						<font>
								<font face="Times New Roman">用户在对Use
Stories进行优先级的排序后，这个顺序虽然不是在未来完成整个系统的过程中实现Use
Story的顺序（因为需求是易变的），然而一般情况下这个Use Stories的优先级排序，却决定了第一次 迭代的开发内容。优先级高的Use
Story应该先完成，这是直面风险的一种方式，按照XP的描述来看， 用户认为优先级越高的Use
Story所存在商业价值就越大，当然其风险和不确定性也就越大，所以我们应该先实现它。 </font>
						</font>
				</font>
		</p>
		<p>
				<font size="2">
						<font>
								<font face="Times New Roman">在用户确定了第一次迭代过程中所需要开发
的Use Stories后，那么我们就可以将这些Use Stories分解成相应的任务了，注意，用户虽然为第一次迭代选择了相应的Use
Sotries，但是这些Use Stories却未必会在第一次迭代当中完成，因为正如前面所说Use
Stories的作用只是一个占位符，我们通过Use
Stories所了解的系统功能只是极为抽象的内容，单凭这些内容我们是无法估算出完成一个认识所需要的具体时间的，所以在决定开发一个Use
Story的时候需要对这个Use Story进行进一步的分析，将这个Use Story拆解成若干个任务。折解的目的是Use
Story所被折解成的任务将都是可以进行开发时间评估的（大小基本可知），只有这样的任务开发人员实际工作起来才会感觉到心里有数，一个Use
Story所表示的抽象范围比较广，可以先将这个Use Story折解成若干个Use Case或者更小的Use Story（再强调一次，Use
Case要比Use Story的抽象极别低），然后再将具体的Use
Case折解成具体可以进行评估的任务。而如果我们对一个任务无法进行评估的话，那么可能就说明我们任务还有细分的余地，我们可以将它拆解成更小的任务
（当然这里有一种情况是由于团队内的开发人员都不清楚任务所涉及到的专业知识，所以造成无法对任务的工作时间进行评估，在这种情况下，可能就需要一个此领
域的专家帮忙了，或者如果没有这样条件的话，那么开发团队在经过对这种专业知识的短时间学习后再对任务进行评估？，或者重新评估使用此技术所付出的代价是
否可以在一定的成本范围之内）。 </font>
						</font>
				</font>
		</p>
		<p>
				<font size="2">
						<font>
								<font face="Times New Roman">在对Use
Story进行拆解的过程当中经常会遇到的一个问题就是可以从进一步的分析过程当中得到一些浅在的Use Story或者Use
Case。可以将这些Use Story或者Use
Case加入到列表，然后评估其是否有必要被加入到本次迭代，如果有的话，那么一并进行分析，如果没有的话，那么将其安排到其它的迭代中来完成。 </font>
						</font>
				</font>
		</p>
		<p>
				<font size="2">
						<font>
								<font face="Times New Roman">在拆解任务的过程中，我们应该保持对核心
问题的注意力，举个例子来说，比如说我们要处理一个发送信息到指定用户的Use Case，这个Use
Case核心的问题就是将信息成功的发送到指定用户处，而在拆解这个Use
Case的时候我们发现校验收件人用户是否有效的操作也是一个相对比较复杂且工作量比较大的工作，因为它涉及到与帐号系统的配合工作。在这个时候我们所采
取的策略就应该是将用户校验操作视为完成整个发送信息过程操作当中的非核心步骤，不需要对这个问题太过纠缠。在分析的时候只需要把它当做一步操作，而在实
做的时候也只需要定义一个用户校验的接口，然后使用Mock对象的技术来满足发送邮件时对用户校验系统的需求即可。 </font>
						</font>
				</font>
		</p>
		<p>
				<font size="2">
						<font>
								<font face="Times New Roman">另外在拆解任务的过程当中还应该注意的一
点是，不应该让我们所能够承受的复杂度和负载度超标，比如说当我们发现从一个Use Story分解出来的Use
Case复杂的足以让我们不能够一次对付他们的时候就应该明智的将对Use Story的分析改成对某一个或者某几个特定Use
Case的分析。只有使用客中化整为零，各个击破的策略才能够使我们在面对大型软件的时候保持我们的控制力。  <br /> <br />Archie的评价  2004.10.07  <br />虽然不能准确的对故事进行估算，但是还是要进行估算的，而且团队的速度也是用故事的度量单位来衡量，而不是任务。 <br />要进行估算就要对故事进行比较详细的了解，要和客户进行大量的沟通，了解到什么程度呢？能进行估算了为止。  </font>
						</font>
				</font>
		</p>
<img src ="http://www.blogjava.net/wfeng007/aggbug/38860.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wfeng007/" target="_blank">wfeng007</a> 2006-04-03 11:24 <a href="http://www.blogjava.net/wfeng007/archive/2006/04/03/38860.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>interface 与 abstract ...</title><link>http://www.blogjava.net/wfeng007/archive/2006/03/28/37740.html</link><dc:creator>wfeng007</dc:creator><author>wfeng007</author><pubDate>Tue, 28 Mar 2006 02:43:00 GMT</pubDate><guid>http://www.blogjava.net/wfeng007/archive/2006/03/28/37740.html</guid><wfw:comment>http://www.blogjava.net/wfeng007/comments/37740.html</wfw:comment><comments>http://www.blogjava.net/wfeng007/archive/2006/03/28/37740.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/wfeng007/comments/commentRss/37740.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wfeng007/services/trackbacks/37740.html</trackback:ping><description><![CDATA[    虽然一直觉得 interface 和abstract其实各自作用不同，而且有各自所适应的情况。但是就是说不清楚，他们在使用时应该在注意的区别。<br />    看了 Erich Gamma的说法，恍然大悟。java interface作为接口时是应该相对稳定的。一旦你修改了一个接口，其实现都会作废，需要按照从新修改来遵守这个已发布的契约。而从，领域抽象的角度来看。java 中的interface 应该作为一个行为契约来用。所以，只有相对稳定的行为集可以作为一个接口公告和契约发布出来，让client调用，这才是java interface的真实含义。比如，发布一个Transcation interface作为，事务行为契约再好不过了。<br />    而abstract作为接口时是相对稳定性是宽松的。如果你想增加一个方法，来让一个比较特殊的实例来作为实现。你可以直接在抽象方法实现一个默认方法，这样其他子类就不会受到较大的牵连。从领域抽象的角度来说，对象既可以描述实体也可以描述行为。然而，通常一旦描述行为，使用整个对象来描述一个整体行为的（注意不是一个行为集）。所以，总体来说，abstract应该用以描述内部行为相对不太确定的实体，或内部子行为不太确定的行为的。比如，java collection框架中的AbstractList<br />    Erich Gamma: 接口提取出对象之间的协作关系。接口是独立于实现细节的，而且它定义了协作的语汇（vocabulary）。一旦我理解了接口，我就理解了系统的大部分。为什么？因为当我理解了所有接口以后，我应该就能够理解关于这个问题的语汇。<br />    精辟啊。。。系统分治以后，整个系统的复杂度就转化为子系统之间的交互上了。一旦定义了套接口，那么对于各个子系统来说已经制导整个系统了，复杂的问题就变得简单了。<img src ="http://www.blogjava.net/wfeng007/aggbug/37740.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wfeng007/" target="_blank">wfeng007</a> 2006-03-28 10:43 <a href="http://www.blogjava.net/wfeng007/archive/2006/03/28/37740.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用例建模。。拙见。。</title><link>http://www.blogjava.net/wfeng007/archive/2006/03/17/35774.html</link><dc:creator>wfeng007</dc:creator><author>wfeng007</author><pubDate>Fri, 17 Mar 2006 01:49:00 GMT</pubDate><guid>http://www.blogjava.net/wfeng007/archive/2006/03/17/35774.html</guid><wfw:comment>http://www.blogjava.net/wfeng007/comments/35774.html</wfw:comment><comments>http://www.blogjava.net/wfeng007/archive/2006/03/17/35774.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wfeng007/comments/commentRss/35774.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wfeng007/services/trackbacks/35774.html</trackback:ping><description><![CDATA[    用例建模时总是把握不住宏观与细节程度，并且对于一些用例本身不能很好描述的需求进行建模。几乎每次分析都是步履艰难。最近找了些资料看，才发现犯忌讳。。。赫赫。。<br />    吸取了之前教训，现在个人吧用例建模分为两大步骤。首先是宏观的完全出自用户的功能事例。当上一部基本完成后，就需要需求分析人员作进一步细化，并最终通过用户审核的。之前一步可以称为基础需求用例，后者就是次用例了。。：）<br />    基础用例建模可以遵照经典用例分析的一些步骤。有一点区别，对于本系统完全被动的参与者也可以作为首选分析对象。因为有时候用户虽然不知道要对系统干啥，但是却非常关注自己得到系统的服务。一个用例建立可以有如下步骤:<br />    1。选择外部系统的参与者，包括对于本系统完全被动的参与者。<br />    2。从参与者角度出发, 对参与者交互的每件事列出步骤。<br />    3。不作任何多余的分析。。记住了，这要用户给出就写下来。。<br />    这样只要用户可以给出的都要记录下来,其他都不作。那还有很多参与者并不是人，怎么办？？。。。很遗憾只能靠分析人员自己站在这些参与者角度假设了。同样不要做过多分析，只要假设这些参与者只了解系统的边界部分即可。<br />    一般对于快速开发的项目基础用例建立完成就可以直接进行设计甚至编码工作了，因为之后的分析可能会消耗大量时间。把这些事留给重构，或下一个迭代版本吧。。。咔咔咔。。。只要你不担心这些的后果。。。<br />    次用例建模完全建立在基础用例上。这是为了分析出进一步需求或者说对于基础需求中不明确的部分作出描述。该步骤分析人员可以完全先自己分析，但必须得到用户审核。<br />    步骤如下：    <br />    1。考虑一些可变情况，把他们创建为扩展用例。<br />    2。复审不同用例的描述，找出其中的相同点，抽出相同点作为共同的用例。<br />    3。分析之前没有主动参与者的用例，使其必须由参与者。（还记得基础用例可以有对于本系统完全被动的参与者么？？ ：）<br />    注意点：虽然一般用例在建模时有很多限制，但是个人觉得在作次用例建模时，应该放开自由发挥只要能说明问题即可。include extends use ... 随便,不用太担心这些东西的定义。<br /><br />    对于有经验的领域可以多次进行次用例迭代，从而减少系统整体开发的迭代次数。只要做得好完全可以做到只用瀑布式方式开发。（当然个人觉得不太可能做到赫赫，用户是善变的。）<br /><br />    参考：<br />   <a href="http://www.contextfree.net/wangyw/oo_class/use_case.html">咏武的“用例建模”</a><br />    <br /><img src ="http://www.blogjava.net/wfeng007/aggbug/35774.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wfeng007/" target="_blank">wfeng007</a> 2006-03-17 09:49 <a href="http://www.blogjava.net/wfeng007/archive/2006/03/17/35774.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>初见 springside</title><link>http://www.blogjava.net/wfeng007/archive/2006/03/15/35366.html</link><dc:creator>wfeng007</dc:creator><author>wfeng007</author><pubDate>Wed, 15 Mar 2006 02:59:00 GMT</pubDate><guid>http://www.blogjava.net/wfeng007/archive/2006/03/15/35366.html</guid><wfw:comment>http://www.blogjava.net/wfeng007/comments/35366.html</wfw:comment><comments>http://www.blogjava.net/wfeng007/archive/2006/03/15/35366.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/wfeng007/comments/commentRss/35366.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wfeng007/services/trackbacks/35366.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 江南白衣的springside诞生已经有一段时间了。。。 可惜我这几天刚刚见到，惭愧啊。。。 挺有兴致浏览了一下功能说明。
我考，那么多啊。。。真够厉害的，还有居然用Groovy写业务的计划。。。不过。。。需求好像过于笼统吧。。赫赫。
比如，功能上是不是还有应该有收藏夹这样的东东。反正dearbook上是有的。。。赫赫<br>
&nbsp;&nbsp;&nbsp; 下载下来初步看了一下。好的地方不说了毕竟目标是best practise。。。 只是奇怪。。对于所有的业务数据的Dao都不提供行限制（就是UI上讲的分页）的逻辑。比如：<br>
&nbsp;&nbsp;&nbsp; <div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 128, 128);">&nbsp;1</span>&nbsp;<span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 128, 0);">/**</span><span style="color: rgb(0, 128, 0);"><br></span><span style="color: rgb(0, 128, 128);">&nbsp;2</span>&nbsp;<span style="color: rgb(0, 128, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;按map中的条件进行查询。<br></span><span style="color: rgb(0, 128, 128);">&nbsp;3</span>&nbsp;<span style="color: rgb(0, 128, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 128, 0);">*/</span><span style="color: rgb(0, 0, 0);"><br></span><span style="color: rgb(0, 128, 128);">&nbsp;4</span>&nbsp;<span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);">&nbsp;List&nbsp;findOrders(Map&nbsp;map)&nbsp;</span><span style="color: rgb(0, 0, 255);">throws</span><span style="color: rgb(0, 0, 0);">&nbsp;ParseException&nbsp;{<br></span><span style="color: rgb(0, 128, 128);">&nbsp;5</span>&nbsp;<span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Criteria&nbsp;criteria&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;getSession().createCriteria(getEntityClass());<br></span><span style="color: rgb(0, 128, 128);">&nbsp;6</span>&nbsp;<span style="color: rgb(0, 0, 0);"><br></span><span style="color: rgb(0, 128, 128);">&nbsp;7</span>&nbsp;<span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;id&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;(String)&nbsp;map.get(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">id</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br></span><span style="color: rgb(0, 128, 128);">&nbsp;8</span>&nbsp;<span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);">&nbsp;(StringUtils.isNotBlank(id))<br></span><span style="color: rgb(0, 128, 128);">&nbsp;9</span>&nbsp;<span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;criteria.add(Restrictions.eq(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">id</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,&nbsp;</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;Integer(id)));<br></span><span style="color: rgb(0, 128, 128);">10</span>&nbsp;<span style="color: rgb(0, 0, 0);"><br></span><span style="color: rgb(0, 128, 128);">11</span>&nbsp;<span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;beginDate&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;(String)&nbsp;map.get(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">beginDate</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br></span><span style="color: rgb(0, 128, 128);">12</span>&nbsp;<span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);">&nbsp;(StringUtils.isNotEmpty(beginDate))<br></span><span style="color: rgb(0, 128, 128);">13</span>&nbsp;<span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;criteria.add(Restrictions.ge(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">shipdate</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,&nbsp;DateUtil.parse(beginDate,<br></span><span style="color: rgb(0, 128, 128);">14</span>&nbsp;<span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">yyyy-MM-DD</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">)));<br></span><span style="color: rgb(0, 128, 128);">15</span>&nbsp;<span style="color: rgb(0, 0, 0);"><br></span><span style="color: rgb(0, 128, 128);">16</span>&nbsp;<span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;endDate&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;(String)&nbsp;map.get(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">endDate</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br></span><span style="color: rgb(0, 128, 128);">17</span>&nbsp;<span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);">&nbsp;(StringUtils.isNotEmpty(endDate))<br></span><span style="color: rgb(0, 128, 128);">18</span>&nbsp;<span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;criteria.add(Restrictions.le(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">shipdate</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,&nbsp;DateUtil.parse(endDate,<br></span><span style="color: rgb(0, 128, 128);">19</span>&nbsp;<span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">yyyy-MM-DD</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">)));<br></span><span style="color: rgb(0, 128, 128);">20</span>&nbsp;<span style="color: rgb(0, 0, 0);"><br></span><span style="color: rgb(0, 128, 128);">21</span>&nbsp;<span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;customer&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;(String)&nbsp;map.get(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">customer</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br></span><span style="color: rgb(0, 128, 128);">22</span>&nbsp;<span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);">&nbsp;(StringUtils.isNotEmpty(customer))<br></span><span style="color: rgb(0, 128, 128);">23</span>&nbsp;<span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;criteria.createAlias(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">customer</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">c</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">).add(<br></span><span style="color: rgb(0, 128, 128);">24</span>&nbsp;<span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Restrictions.like(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">c.name</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">%</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);">&nbsp;customer&nbsp;</span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">%</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">));<br></span><span style="color: rgb(0, 128, 128);">25</span>&nbsp;<span style="color: rgb(0, 0, 0);"><br></span><span style="color: rgb(0, 128, 128);">26</span>&nbsp;<span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;status&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;(String)&nbsp;map.get(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">status</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br></span><span style="color: rgb(0, 128, 128);">27</span>&nbsp;<span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);">&nbsp;(StringUtils.isNotEmpty(status)&nbsp;</span><span style="color: rgb(0, 0, 0);">&amp;&amp;</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">!</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">all</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">.equals(status))<br></span><span style="color: rgb(0, 128, 128);">28</span>&nbsp;<span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;criteria.add(Restrictions.eq(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">status</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,&nbsp;status));<br></span><span style="color: rgb(0, 128, 128);">29</span>&nbsp;<span style="color: rgb(0, 0, 0);"><br></span><span style="color: rgb(0, 128, 128);">30</span>&nbsp;<span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;criteria.addOrder(org.hibernate.criterion.Order.asc(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">shipdate</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">));<br></span><span style="color: rgb(0, 128, 128);">31</span>&nbsp;<span style="color: rgb(0, 0, 0);"><br></span><span style="color: rgb(0, 128, 128);">32</span>&nbsp;<span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);">&nbsp;criteria.list();<br></span><span style="color: rgb(0, 128, 128);">33</span>&nbsp;<span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;}</span></div><br>
这个是定单查找的 finder 虽然增加了这些条件，还是可能会有很多记录被读到中间件服务器的内存中吧。也许以后会有的吧。或者我没看到？？。。。<img src ="http://www.blogjava.net/wfeng007/aggbug/35366.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wfeng007/" target="_blank">wfeng007</a> 2006-03-15 10:59 <a href="http://www.blogjava.net/wfeng007/archive/2006/03/15/35366.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>郁闷 大学同学居然中了 ipod...</title><link>http://www.blogjava.net/wfeng007/archive/2006/03/13/35054.html</link><dc:creator>wfeng007</dc:creator><author>wfeng007</author><pubDate>Mon, 13 Mar 2006 08:00:00 GMT</pubDate><guid>http://www.blogjava.net/wfeng007/archive/2006/03/13/35054.html</guid><wfw:comment>http://www.blogjava.net/wfeng007/comments/35054.html</wfw:comment><comments>http://www.blogjava.net/wfeng007/archive/2006/03/13/35054.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/wfeng007/comments/commentRss/35054.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wfeng007/services/trackbacks/35054.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 上周一，大学同学陈X居然在sun技术日活动中抽到大奖。一个iPod -_-b。然后在台上说:“java其实是比较容易的语言...”。本人在这里严重鄙视其人品，居然在关键时刻大爆发说...<br><img src ="http://www.blogjava.net/wfeng007/aggbug/35054.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wfeng007/" target="_blank">wfeng007</a> 2006-03-13 16:00 <a href="http://www.blogjava.net/wfeng007/archive/2006/03/13/35054.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>