﻿<?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-憨厚生-随笔分类-设计相关</title><link>http://www.blogjava.net/hulizhong/category/38139.html</link><description>----Java's Slave----&lt;br&gt;
***Java's Host***</description><language>zh-cn</language><lastBuildDate>Fri, 06 Nov 2009 01:41:35 GMT</lastBuildDate><pubDate>Fri, 06 Nov 2009 01:41:35 GMT</pubDate><ttl>60</ttl><item><title>设计模式图</title><link>http://www.blogjava.net/hulizhong/archive/2009/11/03/300830.html</link><dc:creator>二胡</dc:creator><author>二胡</author><pubDate>Tue, 03 Nov 2009 01:40:00 GMT</pubDate><guid>http://www.blogjava.net/hulizhong/archive/2009/11/03/300830.html</guid><wfw:comment>http://www.blogjava.net/hulizhong/comments/300830.html</wfw:comment><comments>http://www.blogjava.net/hulizhong/archive/2009/11/03/300830.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/hulizhong/comments/commentRss/300830.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hulizhong/services/trackbacks/300830.html</trackback:ping><description><![CDATA[<img height="620" alt="" src="http://www.blogjava.net/images/blogjava_net/hulizhong/oo.jpg" width="527" border="0" /><img src ="http://www.blogjava.net/hulizhong/aggbug/300830.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hulizhong/" target="_blank">二胡</a> 2009-11-03 09:40 <a href="http://www.blogjava.net/hulizhong/archive/2009/11/03/300830.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>大话之观察者模式</title><link>http://www.blogjava.net/hulizhong/archive/2009/07/07/285785.html</link><dc:creator>二胡</dc:creator><author>二胡</author><pubDate>Tue, 07 Jul 2009 04:34:00 GMT</pubDate><guid>http://www.blogjava.net/hulizhong/archive/2009/07/07/285785.html</guid><wfw:comment>http://www.blogjava.net/hulizhong/comments/285785.html</wfw:comment><comments>http://www.blogjava.net/hulizhong/archive/2009/07/07/285785.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.blogjava.net/hulizhong/comments/commentRss/285785.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hulizhong/services/trackbacks/285785.html</trackback:ping><description><![CDATA[<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;大家都知道，毛主席对游击战有个十六字诀："敌进我退，敌驻我扰，敌疲我打，敌退我追"。<br />
我对此的理解就是当敌人的形势发生了变化，我们行动也要相应变动。其实在软件开发过程中也有类式情景。当A对象的状态变化的时候，B对象的状态也要相应变化。我们常用观察者模式解决此类问题。代码如下,可能和大家平常见的观察者模式的代码实现不太一样，其实原理都是一样的。<br />
&nbsp;&nbsp;&nbsp;&nbsp;在下面的代码里，我方的情报人员显的很重要。<span style="color: red">即被观察者要有到观察者的引用。</span></p>
<p>&nbsp;public class 敌人 {<br />
&nbsp;private 我 my;</p>
<p>&nbsp;public 敌人() {<br />
&nbsp;&nbsp;my = new 我(); /* 哈哈,敌人内部的我方情报人员 */<br />
&nbsp;}</p>
<p>&nbsp;public void 进() {<br />
&nbsp;&nbsp;System.out.println("--敌进--");<br />
&nbsp;&nbsp;my.退();<br />
&nbsp;}</p>
<p>&nbsp;public void 驻() {<br />
&nbsp;&nbsp;System.out.println("--敌驻--");<br />
&nbsp;&nbsp;my.扰();<br />
&nbsp;}</p>
<p>&nbsp;public void 疲() {<br />
&nbsp;&nbsp;System.out.println("--敌疲--");<br />
&nbsp;&nbsp;my.打();<br />
&nbsp;}</p>
<p>&nbsp;public void 退() {<br />
&nbsp;&nbsp;System.out.println("--敌退--");<br />
&nbsp;&nbsp;my.追();<br />
&nbsp;}<br />
}</p>
<p><br />
&nbsp;public class 我 {<br />
&nbsp;public void 退() {<br />
&nbsp;&nbsp;System.out.println("--我退--");<br />
&nbsp;}</p>
<p>&nbsp;public void 扰() {<br />
&nbsp;&nbsp;System.out.println("--我扰--");<br />
&nbsp;}</p>
<p>&nbsp;public void 打() {<br />
&nbsp;&nbsp;System.out.println("--我打--");<br />
&nbsp;}</p>
<p>&nbsp;public void 追() {<br />
&nbsp;&nbsp;System.out.println("--我追--");<br />
&nbsp;}<br />
}</p>
<p>&nbsp;</p><img src ="http://www.blogjava.net/hulizhong/aggbug/285785.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hulizhong/" target="_blank">二胡</a> 2009-07-07 12:34 <a href="http://www.blogjava.net/hulizhong/archive/2009/07/07/285785.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>深入浅出单实例Singleton设计模式</title><link>http://www.blogjava.net/hulizhong/archive/2009/07/06/285685.html</link><dc:creator>二胡</dc:creator><author>二胡</author><pubDate>Mon, 06 Jul 2009 06:25:00 GMT</pubDate><guid>http://www.blogjava.net/hulizhong/archive/2009/07/06/285685.html</guid><wfw:comment>http://www.blogjava.net/hulizhong/comments/285685.html</wfw:comment><comments>http://www.blogjava.net/hulizhong/archive/2009/07/06/285685.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/hulizhong/comments/commentRss/285685.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hulizhong/services/trackbacks/285685.html</trackback:ping><description><![CDATA[转 http://blog.csdn.net/haoel/archive/2009/03/26/4028232.aspx<br />
<br />
<pre style="text-align: center;"><strong><span style="font-size: large;">深入浅出单实例Singleton设计模式</span></strong></pre>
<p style="text-align: center;"><strong><span style="font-size: small;">陈皓</span></strong></p>
<h1>前序</h1>
<p>单实例Singleton设计模式可能是被讨论和使用的最广泛的一个设计模式了，这可能也是面试中问得最多的一个设计模式了。这个设计模式主要目的
是想在整个系统中只能出现一个类的实例。这样做当然是有必然的，比如你的软件的全局配置信息，或者是一个Factory，或是一个主控类，等等。你希望这
个类在整个系统中只能出现一个实例。当然，作为一个技术负责人的你，你当然有权利通过使用非技术的手段来达到你的目的。比如：你在团队内部明文规
定，&#8220;XX类只能有一个全局实例，如果某人使用两次以上，那么该人将被处于2000元的罚款！&#8221;（呵呵），你当然有权这么做。但是如果你的设计的是东西是
一个类库，或是一个需要提供给用户使用的API，恐怕你的这项规定将会失效。因为，你无权要求别人会那么做。所以，这就是为什么，我们希望通过使用技术的
手段来达成这样一个目的的原因。</p>
<p>本文会带着你深入整个Singleton的世界，当然，我会放弃使用C++语言而改用Java语言，因为使用Java这个语言可能更容易让我说明一些事情。</p>
<h1><br />
Singleton的教学版本</h1>
<p>这里，我将直接给出一个Singleton的简单实现，因为我相信你已经有这方面的一些基础了。我们姑且把这具版本叫做1.0版</p>
<div class="dp-highlighter">
<ol class="dp-j">
    <li class="alt"><span class="comment"><span style="color: #008200;">//&nbsp;version&nbsp;1.0 </span></span>&nbsp;&nbsp;</li>
    <li><span class="keyword"><strong><span style="color: #006699;">public</span></strong></span>&nbsp;<span class="keyword"><strong><span style="color: #006699;">class</span></strong></span>&nbsp;Singleton &nbsp;&nbsp;</li>
    <li class="alt">{ &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword"><strong><span style="color: #006699;">private</span></strong></span>&nbsp;<span class="keyword"><strong><span style="color: #006699;">static</span></strong></span>&nbsp;<span class="keyword"><strong><span style="color: #006699;">final</span></strong></span>&nbsp;Singleton&nbsp;singleton&nbsp;=&nbsp;<span class="keyword"><strong><span style="color: #006699;">null</span></strong></span>; &nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword"><strong><span style="color: #006699;">private</span></strong></span>&nbsp;Singleton() &nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword"><strong><span style="color: #006699;">public</span></strong></span>&nbsp;<span class="keyword"><strong><span style="color: #006699;">static</span></strong></span>&nbsp;Singleton&nbsp;getInstance() &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword"><strong><span style="color: #006699;">if</span></strong></span>&nbsp;(singleton==&nbsp;<span class="keyword"><strong><span style="color: #006699;">null</span></strong></span>) &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;singleton=&nbsp;<span class="keyword"><strong><span style="color: #006699;">new</span></strong></span>&nbsp;Singleton(); &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword"><strong><span style="color: #006699;">return</span></strong></span>&nbsp;singleton; &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</li>
    <li class="alt">}&nbsp;&nbsp;
    <pre name="code_lighted" class="java" style="display: none;">&nbsp;</pre>
    </li>
</ol>
</div>
<p>在上面的实例中，我想说明下面几个Singleton的特点：（下面这些东西可能是尽人皆知的，没有什么新鲜的）</p>
<ol>
    <li>私有（private）的构造函数，表明这个类是不可能形成实例了。这主要是怕这个类会有多个实例。 </li>
    <li>即然这个类是不可能形成实例，那么，我们需要一个静态的方式让其形成实例：getInstance()。注意这个方法是在new自己，因为其可以访问私有的构造函数，所以他是可以保证实例被创建出来的。 </li>
    <li>在getInstance()中，先做判断是否已形成实例，如果已形成则直接返回，否则创建实例。 </li>
    <li>所形成的实例保存在自己类中的私有成员中。 </li>
    <li>我们取实例时，只需要使用Singleton.getInstance()就行了。 </li>
</ol>
<p>当然，如果你觉得知道了上面这些事情后就学成了，那我给你当头棒喝一下了，事情远远没有那么简单。</p>
<h1>Singleton的实际版本</h1>
<p>上面的这个程序存在比较严重的问题，因为是全局性的实例，所以，在多线程情况下，所有的全局共享的东西都会变得非常的危险，这个也一样，在多线程情
况下，如果多个线程同时调用getInstance()的话，那么，可能会有多个进程同时通过 (singleton==
null)的条件检查，于是，多个实例就创建出来，并且很可能造成内存泄露问题。嗯，熟悉多线程的你一定会说——&#8220;我们需要线程互斥或同步&#8221;，没错，我们
需要这个事情，于是我们的Singleton升级成1.1版，如下所示：</p>
<div class="dp-highlighter">
<ol class="dp-j">
    <li class="alt"><span class="comment"><span style="color: #008200;">//&nbsp;version&nbsp;1.1 </span></span>&nbsp;&nbsp;</li>
    <li><span class="keyword"><strong><span style="color: #006699;">public</span></strong></span>&nbsp;<span class="keyword"><strong><span style="color: #006699;">class</span></strong></span>&nbsp;Singleton &nbsp;&nbsp;</li>
    <li class="alt">{ &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword"><strong><span style="color: #006699;">private</span></strong></span>&nbsp;<span class="keyword"><strong><span style="color: #006699;">static</span></strong></span>&nbsp;<span class="keyword"><strong><span style="color: #006699;">final</span></strong></span>&nbsp;Singleton&nbsp;singleton&nbsp;=&nbsp;<span class="keyword"><strong><span style="color: #006699;">null</span></strong></span>; &nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword"><strong><span style="color: #006699;">private</span></strong></span>&nbsp;Singleton() &nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword"><strong><span style="color: #006699;">public</span></strong></span>&nbsp;<span class="keyword"><strong><span style="color: #006699;">static</span></strong></span>&nbsp;Singleton&nbsp;getInstance() &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword"><strong><span style="color: #006699;">if</span></strong></span>&nbsp;(singleton==&nbsp;<span class="keyword"><strong><span style="color: #006699;">null</span></strong></span>) &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword"><strong><span style="color: #006699;">synchronized</span></strong></span>&nbsp;(Singleton.<span class="keyword"><strong><span style="color: #006699;">class</span></strong></span>)&nbsp;{ &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;singleton=&nbsp;<span class="keyword"><strong><span style="color: #006699;">new</span></strong></span>&nbsp;Singleton(); &nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword"><strong><span style="color: #006699;">return</span></strong></span>&nbsp;singleton; &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</li>
    <li class="alt">}&nbsp;&nbsp;</li>
</ol>
</div>
<pre name="code_lighted" class="java" style="display: none;">&nbsp;</pre>
<p>嗯，使用了Java的synchronized方法，看起来不错哦。应该没有问题了吧？！错！这还是有问题！为什么呢？前面已经说过，如果有多个线
程同时通过(singleton==
null)的条件检查（因为他们并行运行），虽然我们的synchronized方法会帮助我们同步所有的线程，让我们并行线程变成串行的一个一个去
new，那不还是一样的吗？同样会出现很多实例。嗯，确实如此！看来，还得把那个判断(singleton==
null)条件也同步起来。于是，我们的Singleton再次升级成1.2版本，如下所示：</p>
<div class="dp-highlighter">
<div class="bar">
<div class="tools">&nbsp;</div>
</div>
<ol class="dp-j">
    <li class="alt"><span class="comment"><span style="color: #008200;">//&nbsp;version&nbsp;1.2 </span></span>&nbsp;&nbsp;</li>
    <li><span class="keyword"><strong><span style="color: #006699;">public</span></strong></span>&nbsp;<span class="keyword"><strong><span style="color: #006699;">class</span></strong></span>&nbsp;Singleton &nbsp;&nbsp;</li>
    <li class="alt">{ &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword"><strong><span style="color: #006699;">private</span></strong></span>&nbsp;<span class="keyword"><strong><span style="color: #006699;">static</span></strong></span>&nbsp;<span class="keyword"><strong><span style="color: #006699;">final</span></strong></span>&nbsp;Singleton&nbsp;singleton&nbsp;=&nbsp;<span class="keyword"><strong><span style="color: #006699;">null</span></strong></span>; &nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword"><strong><span style="color: #006699;">private</span></strong></span>&nbsp;Singleton() &nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword"><strong><span style="color: #006699;">public</span></strong></span>&nbsp;<span class="keyword"><strong><span style="color: #006699;">static</span></strong></span>&nbsp;Singleton&nbsp;getInstance() &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword"><strong><span style="color: #006699;">synchronized</span></strong></span>&nbsp;(Singleton.<span class="keyword"><strong><span style="color: #006699;">class</span></strong></span>) &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword"><strong><span style="color: #006699;">if</span></strong></span>&nbsp;(singleton==&nbsp;<span class="keyword"><strong><span style="color: #006699;">null</span></strong></span>) &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;singleton=&nbsp;<span class="keyword"><strong><span style="color: #006699;">new</span></strong></span>&nbsp;Singleton(); &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword"><strong><span style="color: #006699;">return</span></strong></span>&nbsp;singleton; &nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</li>
    <li>}&nbsp;&nbsp;</li>
</ol>
</div>
<pre name="code_lighted" class="java" style="display: none;">&nbsp;</pre>
<p>不错不错，看似很不错了。在多线程下应该没有什么问题了，不是吗？的确是这样的，1.2版的Singleton在多线程下的确没有问题了，因为我们
同步了所有的线程。只不过嘛&#8230;&#8230;，什么？！还不行？！是的，还是有点小问题，我们本来只是想让new这个操作并行就可以了，现在，只要是进入
getInstance()的线程都得同步啊，注意，创建对象的动作只有一次，后面的动作全是读取那个成员变量，这些读取的动作不需要线程同步啊。这样的
作法感觉非常极端啊，为了一个初始化的创建动作，居然让我们达上了所有的读操作，严重影响后续的性能啊！</p>
<p>还得改！嗯，看来，在线程同步前还得加一个(singleton== null)的条件判断，如果对象已经创建了，那么就不需要线程的同步了。OK，下面是1.3版的Singleton。</p>
<div class="dp-highlighter">
<ol class="dp-j">
    <li class="alt"><span class="comment"><span style="color: #008200;">//&nbsp;version&nbsp;1.3 </span></span>&nbsp;&nbsp;</li>
    <li><span class="keyword"><strong><span style="color: #006699;">public</span></strong></span>&nbsp;<span class="keyword"><strong><span style="color: #006699;">class</span></strong></span>&nbsp;Singleton &nbsp;&nbsp;</li>
    <li class="alt">{ &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword"><strong><span style="color: #006699;">private</span></strong></span>&nbsp;<span class="keyword"><strong><span style="color: #006699;">static</span></strong></span>&nbsp;<span class="keyword"><strong><span style="color: #006699;">final</span></strong></span>&nbsp;Singleton&nbsp;singleton&nbsp;=&nbsp;<span class="keyword"><strong><span style="color: #006699;">null</span></strong></span>; &nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword"><strong><span style="color: #006699;">private</span></strong></span>&nbsp;Singleton() &nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword"><strong><span style="color: #006699;">public</span></strong></span>&nbsp;<span class="keyword"><strong><span style="color: #006699;">static</span></strong></span>&nbsp;Singleton&nbsp;getInstance() &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword"><strong><span style="color: #006699;">if</span></strong></span>&nbsp;(singleton==&nbsp;<span class="keyword"><strong><span style="color: #006699;">null</span></strong></span>) &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword"><strong><span style="color: #006699;">synchronized</span></strong></span>&nbsp;(Singleton.<span class="keyword"><strong><span style="color: #006699;">class</span></strong></span>) &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword"><strong><span style="color: #006699;">if</span></strong></span>&nbsp;(singleton==&nbsp;<span class="keyword"><strong><span style="color: #006699;">null</span></strong></span>) &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;singleton=&nbsp;<span class="keyword"><strong><span style="color: #006699;">new</span></strong></span>&nbsp;Singleton(); &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword"><strong><span style="color: #006699;">return</span></strong></span>&nbsp;singleton; &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</li>
    <li class="alt">}&nbsp;&nbsp;</li>
</ol>
</div>
<pre name="code_lighted" class="java" style="display: none;">&nbsp;</pre>
<p>感觉代码开始变得有点罗嗦和复杂了，不过，这可能是最不错的一个版本了，这个版本又叫&#8220;双重检查&#8221;Double-Check。下面是说明：</p>
<ol>
    <li>第一个条件是说，如果实例创建了，那就不需要同步了，直接返回就好了。 </li>
    <li>不然，我们就开始同步线程。 </li>
    <li>第二个条件是说，如果被同步的线程中，有一个线程创建了对象，那么别的线程就不用再创建了。 </li>
</ol>
<p>相当不错啊，干得非常漂亮！请大家为我们的1.3版起立鼓掌！</p>
<h1>Singleton的其它问题</h1>
<p>怎么？还有问题？！当然还有，请记住下面这条规则——&#8220;<strong>无论你的代码写得有多好，其只能在特定的范围内工作，超出这个范围就要出Bug了</strong>&#8221;，这是&#8220;陈式第一定理&#8221;，呵呵。你能想一想还有什么情况会让这个我们上面的代码出问题吗？</p>
<p>在C++下，我不是很好举例，但是在Java的环境下，嘿嘿，还是让我们来看看下面的一些反例和一些别的事情的讨论（<strong>当然，有些反例可能属于钻牛角尖，可能有点学院派，不过也不排除其实际可能性，就算是提个醒吧</strong>）：</p>
<p><strong>其一、Class Loader</strong>。不知道你对Java的Class
Loader熟悉吗？&#8220;类装载器&#8221;？！C++可没有这个东西啊。这是Java动态性的核心。顾名思义，类装载器是用来把类(class)装载进JVM的。
JVM规范定义了两种类型的类装载器：启动内装载器(bootstrap)和用户自定义装载器(user-defined class
loader)。
在一个JVM中可能存在多个ClassLoader，每个ClassLoader拥有自己的NameSpace。一个ClassLoader只能拥有一个
class对象类型的实例，但是不同的ClassLoader可能拥有相同的class对象实例，这时可能产生致命的问题。如ClassLoaderA，
装载了类A的类型实例A1，而ClassLoaderB，也装载了类A的对象实例A2。逻辑上讲A1=A2，但是由于A1和A2来自于不同的
ClassLoader，它们实际上是完全不同的，如果A中定义了一个静态变量c，则c在不同的ClassLoader中的值是不同的。</p>
<p>于是，如果咱们的Singleton 1.3版本如果面对着多个Class Loader会怎么样？呵呵，多个实例同样会被多个Class
Loader创建出来，当然，这个有点牵强，不过他确实存在。难道我们还要整出个1.4版吗？可是，我们怎么可能在我的Singleton类中操作
Class Loader啊？是的，你根本不可能。在这种情况下，你能做的只有是——&#8220;保证多个Class
Loader不会装载同一个Singleton&#8221;。</p>
<p><strong>其二、序例化。</strong>如果我们的这个Singleton类是一个关于我们程序配置信息的类。我们需要它有序列化的功能，那么，当反序列化的时候，我们将无法控制别人不多次反序列化。不过，我们可以利用一下Serializable接口的readResolve()方法，比如：</p>
<div class="dp-highlighter">
<ol class="dp-j">
    <li class="alt"><span class="keyword"><strong><span style="color: #006699;">public</span></strong></span>&nbsp;<span class="keyword"><strong><span style="color: #006699;">class</span></strong></span>&nbsp;Singleton&nbsp;<span class="keyword"><strong><span style="color: #006699;">implements</span></strong></span>&nbsp;Serializable &nbsp;&nbsp;</li>
    <li>{ &nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;&nbsp;&nbsp;...... &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;...... &nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword"><strong><span style="color: #006699;">protected</span></strong></span>&nbsp;Object&nbsp;readResolve() &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword"><strong><span style="color: #006699;">return</span></strong></span>&nbsp;getInstance(); &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</li>
    <li class="alt">}&nbsp;&nbsp;</li>
</ol>
</div>
<pre name="code_lighted" class="java" style="display: none;">&nbsp;</pre>
<p><strong>其三、多个Java虚拟机。</strong>如果我们的程序运行在多个Java的虚拟机中。什么？多个虚拟机？这是一种什么样的情况啊。嗯，这种情况是有点极端，不过还是可能出现，比如EJB或RMI之流的东西。要在这种环境下避免多实例，看来只能通过良好的设计或非技术来解决了。</p>
<p><strong>其四，volatile变量。</strong>关于volatile这个关键字所声明的变量可以被看作是一种
&#8220;程度较轻的同步synchronized&#8221;；与 synchronized 块相比，volatile
变量所需的编码较少，并且运行时开销也较少，但是它所能实现的功能也仅是synchronized的一部分。当然，如前面所述，我们需要的
Singleton只是在创建的时候线程同步，而后面的读取则不需要同步。所以，volatile变量并不能帮助我们即能解决问题，又有好的性能。而且，
这种变量只能在JDK 1.5+版后才能使用。</p>
<p><strong>其五、关于继承。</strong>是的，继承于Singleton后的子类也有可能造成多实例的问题。不过，因为我们早把Singleton的构造函数声明成了私有的，所以也就杜绝了继承这种事情。</p>
<p><strong>其六，关于代码重用。</strong>也话我们的系统中有很多个类需要用到这个模式，如果我们在每一个类都中有这样的代码，那么
就显得有点傻了。那么，我们是否可以使用一种方法，把这具模式抽象出去？在C++下这是很容易的，因为有模板和友元，还支持栈上分配内存，所以比较容易一
些（程序如下所示），Java下可能比较复杂一些，聪明的你知道怎么做吗？</p>
<div class="dp-highlighter">
<ol class="dp-cpp">
    <li class="alt"><span class="keyword"><strong><span style="color: #006699;">template</span></strong></span>&lt;CLASS&nbsp;T&gt;&nbsp;<span class="keyword"><strong><span style="color: #006699;">class</span></strong></span>&nbsp;Singleton &nbsp;&nbsp;</li>
    <li>{ &nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword"><strong><span style="color: #006699;">public</span></strong></span>: &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword"><strong><span style="color: #006699;">static</span></strong></span>&nbsp;T&amp;&nbsp;Instance() &nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword"><strong><span style="color: #006699;">static</span></strong></span>&nbsp;T&nbsp;theSingleInstance;&nbsp;<span class="comment"><span style="color: #008200;">//假设T有一个protected默认构造函数 </span></span>&nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword"><strong><span style="color: #006699;">return</span></strong></span>&nbsp;theSingleInstance; &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</li>
    <li class="alt">}; &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;</li>
    <li class="alt"><span class="keyword"><strong><span style="color: #006699;">class</span></strong></span>&nbsp;OnlyOne&nbsp;:&nbsp;<span class="keyword"><strong><span style="color: #006699;">public</span></strong></span>&nbsp;Singleton&lt;ONLYONE&gt; &nbsp;&nbsp;</li>
    <li>{ &nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword"><strong><span style="color: #006699;">friend</span></strong></span>&nbsp;<span class="keyword"><strong><span style="color: #006699;">class</span></strong></span>&nbsp;Singleton&lt;ONLYONE&gt;; &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;<span class="datatypes">int</span>&nbsp;example_data; &nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword"><strong><span style="color: #006699;">public</span></strong></span>: &nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="datatypes">int</span>&nbsp;GetExampleData()&nbsp;<span class="keyword"><strong><span style="color: #006699;">const</span></strong></span>&nbsp;{<span class="keyword"><strong><span style="color: #006699;">return</span></strong></span>&nbsp;example_data;} &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword"><strong><span style="color: #006699;">protected</span></strong></span>: &nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OnlyOne():&nbsp;example_data(42)&nbsp;{}&nbsp;&nbsp;&nbsp;<span class="comment"><span style="color: #008200;">//&nbsp;默认构造函数 </span></span>&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OnlyOne(OnlyOne&amp;)&nbsp;{} &nbsp;&nbsp;</li>
    <li class="alt">}; &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;</li>
    <li class="alt"><span class="datatypes">int</span>&nbsp;main(&nbsp;) &nbsp;&nbsp;</li>
    <li>{ &nbsp;&nbsp;</li>
    <li class="alt">&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;&lt;&lt;&nbsp;OnlyOne::Instance().GetExampleData()&lt;&lt;&nbsp;endl; &nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword"><strong><span style="color: #006699;">return</span></strong></span>&nbsp;0; &nbsp;&nbsp;</li>
    <li class="alt">}&nbsp;&nbsp;</li>
</ol>
</div>
<pre name="code_lighted" class="c++" style="display: none;">本文同时发表于——酷壳：<a href="http://cocre.com/?p=265">http://cocre.com/?p=265</a></pre>
<p>&nbsp;<strong><span style="font-family: Times New Roman;">(</span></strong><strong><span style="font-family: 宋体;" lang="ZH-CN">转载时请注明作者和出处。未经许可，请勿用于商业用途</span><span style="font-family: Times New Roman;">)</span></strong></p>
<p>（全文完）</p>
<br />
<br /><img src ="http://www.blogjava.net/hulizhong/aggbug/285685.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hulizhong/" target="_blank">二胡</a> 2009-07-06 14:25 <a href="http://www.blogjava.net/hulizhong/archive/2009/07/06/285685.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转 UML建模的要点总结</title><link>http://www.blogjava.net/hulizhong/archive/2009/04/15/265779.html</link><dc:creator>二胡</dc:creator><author>二胡</author><pubDate>Wed, 15 Apr 2009 08:12:00 GMT</pubDate><guid>http://www.blogjava.net/hulizhong/archive/2009/04/15/265779.html</guid><wfw:comment>http://www.blogjava.net/hulizhong/comments/265779.html</wfw:comment><comments>http://www.blogjava.net/hulizhong/archive/2009/04/15/265779.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/hulizhong/comments/commentRss/265779.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hulizhong/services/trackbacks/265779.html</trackback:ping><description><![CDATA[转 http://dev.yesky.com/241/8757741.shtml#pls<br />
<h1 id="artibodyTitle">UML建模的要点总结</h1>
<div id="conauthor"><span>2009-03-18 11:57</span><span>作者：</span><span>出处：天极网</span><span>责任编辑：郑重</span></div>
<div class="topadbg"><span id="ad9">
<div id="ad9ad">
<script language="JavaScript1.1" src="http://ucpn.yesky.com/js.ng/site=yesky&amp;node_yesky=412&amp;page=cont&amp;area=y_inner_under_banner&amp;format=banner&amp;num=1"></script>
<script language="JavaScript1.1" src="http://ucpn.yesky.com/js.ng/site=yesky&amp;node_yesky=412&amp;page=cont&amp;area=y_inner_under_banner&amp;format=banner&amp;num=2"></script>
</div>
</span></div>
<!--正文开始-->
<!-- Error -->
<div class="guanggao"><span id="contentAdv">
<script language="JavaScript1.1" src="http://ucpn.yesky.com/js.ng/site=yesky&amp;node_yesky=412&amp;page=cont&amp;area=yesky_inner_pip&amp;format=picinpic&amp;num=1"></script>
</span></div>
<p>　　预备知识：</p>
<p>　　一、UML的特性与发展现状</p>
<p>　　UML是一种Language(语言)</p>
<p>　　UML是一种Modeling(建模)Language</p>
<p>　　UML是Unified(统一)Modeling Language</p>
<p>　　1、已进入全面应用阶段的事实标准</p>
<p>　　2、应用领域正在逐渐扩展，包括嵌入式系统建模、业务建模、流程建模等多个领域</p>
<p>　　3、成为&#8220;产生式编程&#8221;的重要支持技术：MDA、 可执行UML等</p>
<p>　　二、建模的目的与原则</p>
<p>　　1、帮助我们按照实际情况或按我们需要的样式对系统进行可视化;提供一种详细说明系统的结构或行为的方法;给出一个指导系统构造的模板;对我们所做出的决策进行文档化。</p>
<p>　　2、仅当需要模型时，才构建它。</p>
<p>　　3、选择要创建什么模型对如何动手解决问题和如何形成解决方案有着意义深远的影响;每一种模型可以在不同的精度级别上表示;最好的模型是与现实相联系的;单个模型是不充分的。对每个重要的系统最好用一组几乎独立的模型去处理。</p>
<p>　　三、谁应该建模</p>
<p>　　1、业务建模：以领域专家为主，需求分析人员是主力，系统分析员、架构师可参与</p>
<p>　　2、需求模型：以需求分析人员为主，系统分析员是主力，领域专家提供指导，架构师和资深开发人员参与</p>
<p>　　3、设计模型：高层设计模型以架构师为主，系统分析员从需求方面提供支持，资深开发人员从技术实现方面提供支持。详细设计模型则以资深开发人员为主，架构师提供指导。</p>
<p>　　4、实现模型：以资深开发人员(设计人员)为主，架构师提供总体指导。</p>
<p>　　5、<a href="http://product.yesky.com/database/" class="fllink" target="_bank">数据库</a>模型：以数据库开发人员为主，架构师提供指导，资深开发人员(设计人员)予以配合。</p>
<p>　　正式开始</p>
<p>　　UML组成，三部分(构造块、规则、公共机制)，关系如下图所示：</p>
<p>　　<img alt="" src="http://dev.yesky.com/imagelist/2009/077/1353tg6uie5x.jpg" width="682" height="475" /></p>
<p>　　一、构造块</p>
<p>　　1、构造块是对模型中最具有代表性的成分的抽象</p>
<p>　　建模元素：UML中的名词，它是模型基本物理元素。</p>
<p>　　行为元素：UML中的动词，它是模型中的动态部分，是一种跨越时间、空间的行为。</p>
<p>　　分组元素：UML中的容器，用来组织模型，使模型更加的结构化。</p>
<p>　　注释元素：UML中的解释部分，和代码中的注释语句一样，是用来描述模型的。</p>
<p>　　1.1、建模元素</p>
<p>　　类(class)和对象(object)</p>
<p>　　接口(interface)</p>
<p>　　主动类(active class)</p>
<p>　　用例(use case)</p>
<p>　　协作(collaboration)</p>
<p>　　构件(component)</p>
<p>　　节点(node)</p>
<p>　　类(class)和对象(object)</p>
<p>　　类是对一组具有相同属性、相同操作、相同关系和相同语义的对象的抽象</p>
<p>　　UML中类是用一个矩形表示的，它包含三个区域，最上面是类名、中间是类的属性、最下面是类的方法</p>
<p>　　对象则是类的一个实例 (object is a Instance of Class)</p>
<p>　　接口(interface)</p>
<p>　　接口是描述某个类或构件的一个服务操作集</p>
<p>　　主动类(active class)</p>
<p>　　主动类实际上是一种特殊的类。引用它的原因，实际上是在开发中需要有一些类能够起到 启动控制活动的作用</p>
<p>　　主动类是指其对象至少拥有一个进 程或线程，能够启动控制活动的类</p>
<p>　　用例(use case)</p>
<p>　　用例是著名的大师Ivar Jacobson首先提出的，现已经成为了面向对象<a href="http://product.yesky.com/software/" class="fllink" target="_bank">软件</a>开发中一个需求分析的最常用工具</p>
<p>　　用例实例是在系统中执行的一系列动作，这些动作将生成特定执行者可见的价值结果。一个 用例定义一组用例实例。</p>
<p>　　协作(collaboration)</p>
<p>　　协作定义了一个交互，它是由一组共同工作以提供某协作行为的角色和其他元素构 成的一个群体。</p>
<p>　　对于某个用例的实现就可 以表示为一个协作</p>
<p>　　构件(component)</p>
<p>　　在实际的软件系统中，有许多要比&#8220;类&#8221;更大的实体，例如一个COM组件、一个DLL文件、一个JavaBeans、一个执行文件等等。为了更好地对在UML模型中对它们进行表示，就引入了构件(也译为组件)</p>
<p>　　构件是系统设计的一个模块化部分，它隐藏了内部的实现，对外提供了一组外部接口。在系统中满足相同接口的组件可以自由地替换</p>
<p>　　节点(node)</p>
<p>　　为了能够有效地对部署的结构进行建模，UML引入了节点这一概念，它可以用来描述实际的PC机、打印机、<a href="http://product.yesky.com/service/" class="fllink" target="_bank">服务器</a>等软件运行的基础<a href="http://product.yesky.com/diy/" class="fllink" target="_bank">硬件</a></p>
<p>　　节点是运行时存在的物理元素，它表示了一种可计算的资源，通常至少有存储空间和处理能力</p>
<p>　　1.2、行为元素</p>
<p>　　交互(interaction)： 是在特定语境中，共同完成某个任务的一组对象之间交换的信息集合</p>
<p>　　交互的表示法很简单，就是一条有向直线，并在上面标有操作名</p>
<p>　　状态机(state machine)：是一个对象或交互在生命周期内响应事件所经历的状态序列</p>
<p>　　在UML模型中将状态画为一个圆 角矩形，并在矩形内写出状态名 称及其子状态</p>
<p>　　1.3、分组元素</p>
<p>　　对于一个中大型的软件系统而言，通常会包含大量的类，因此也就会存在大量的结构事物、行为事物，为了能够更加有效地对其进行整合，生成或简或繁、或宏观或微观的模型，就需要对其进行分组。在UML中，提供了&#8220;包(Package)&#8221;来完成这一目标</p>
<p>　　1.4、注释元素</p>
<p>　　结构事物是模型的主要构造块，行为事物则是补充了模型中的动态部分，分组事物而是用来更好地组织模型，似乎已经很完整了。而注释事物则是用来锦上添花的，它是用来在UML模型上添加适当的解释部分</p>
<p>　　2、关系</p>
<p>　　UML模型的关系比较多,下图</p>
<p>　　<img alt="" src="http://dev.yesky.com/imagelist/2009/077/1046862cudqj.jpg" width="684" height="462" /></p>
<p>　　2.1　关联关系</p>
<p>　　关联(Association)表示两个类之间存在某种语义上的联系。关联关系提供了通信的路径，它是所有关系中最通用、语义最弱的。</p>
<p>　　在UML中，使用一条实线来表示关联关系</p>
<p>　　在关联关系中，有两种比较特殊的关系：聚合和组合</p>
<p>　　聚合关系：聚合(Aggregation)是一种特殊形式的关联。聚合表示类之间的关系是整体与部分的关系</p>
<p>　　如果发现&#8220;部分&#8221;类的存在，是完全依赖于&#8220;整体&#8221;类的，那么就应该使用&#8220;组合&#8221;关系来描述</p>
<p>　　组合是聚合的变种，加入了一些重要的语义。也就是说，在一个组合关系中一个对象一次就只是一个组合的一部分，&#8220;整体&#8221;负责&#8220;部分&#8221;的创建和破坏，当&#8220;整体&#8221;被破坏时，&#8220;部分&#8221;也随之消失</p>
<p>　　聚合就像汽车和车胎，汽车坏了胎还可以用。组合就像公司和下属部门，公司倒闭了部门也就不存在了!</p>
<p>　　2.2 　泛化、实现与依赖</p>
<p>　　泛化关系描述了一般事物与该事物中的特殊种类之间的关系，也就是父类与子类之间的关系。</p>
<p>　　实现关系是用来规定接口和实现接口的类或组件之间的关系。接口是操作的集合，这些操作用于规定类或组件的服务。</p>
<p>　　有两个元素X、Y，如果修改元素X的定义可能会引起对另一个元素Y的定义的修改，则称元素Y依赖(Dependency)于元素X。</p>
<p>　　二、规则</p>
<p>　　命名：也就是为事物、关系和图起名字。和任何语言一样，名字都是一个标识符</p>
<p>　　范围：与类的作用域相似.</p>
<p>　　可见性：Public，Protected，Private，Package</p>
<p>　　三、UML公共机制</p>
<p>　　1、规格描述</p>
<p>　　在图形表示法的每个部分后面都有一个规格描述(也称为详述)，它用来对构造块的语法和语义进行文字叙述。这种构思，也就使可视化视图和文字视图的分离 ：</p>
<p>　　2、UML修饰与通用划分</p>
<p>　　在为了更好的表示这些细节，UML中还提供了一些修饰符号，例如不同可视性的符号、用斜体字表示抽象类</p>
<p>　　UML通用划分：</p>
<p>　　1)类与对象的划分：类是一种抽象，对象是一个具体 的实例</p>
<p>　　2)接口与实现的分离：接口是一种声明、是一个契 约，也是服务的入口;实现则是负责实施接口提供 的契约</p>
<p>　　3、UML扩展机制</p>
<p>　　这部分不容易描述，待改(邀月注　2009.2.18)</p>
<p>　　构造型：在实际的建模过程中，可能会需要定义一些特定于某个领域或某个系统的构造块</p>
<p>　　标记值则是用来为事物添加新特性的。标记值的表示方法是用形如&#8220;{标记信息}&#8221;的字符串</p>
<p>　　约束是用来增加新的语义或改变已存在规则的一种机制(自由文本和OCL两种表示法)。约束的表示法和标记值法类似，都是使用花括号括起来的串来表示，不过它是不能够放在元素中的，而是放在相关的元素附近。</p>
<p>　　4、UML视图和图</p>
<p>　　<img alt="" src="http://dev.yesky.com/imagelist/2009/077/hj08p80p322x.jpg" width="684" height="462" /></p>
<p>　　图名　　　　　　　　　　　　功能　　　　　　　　　　　　　　　　备注</p>
<p>　　类图　　　　　　描述类、类的特性以及类之间的关系　　　　　　　　UML 1原有</p>
<p>　　对象图　　　　　描述一个时间点上系统中各个对象的一个快照 　　 UML 1非正式图</p>
<p>　　复合结构图　　　描述类的运行时刻的分解　　　　　　　　　　　　　UML 2.0新增</p>
<p>　　构件图　　　　　描述构件的结构与连接　　　　　　　　　　　　　　UML 1原有</p>
<p>　　部署图　　　　　描述在各个节点上的部署　　　　　　　　　　　　　UML 1原有</p>
<p>　　包图　　　　　　描述编译时的层次结构　　　　　　　　　　　　　　UML中非正式图</p>
<p>　　用例图　　　　　描述用户与系统如何交互　　　　　　　　　　　　　UML 1原有</p>
<p>　　活动图　　　　　描述过程行为与并行行为　　　　　　　　　　　　　UML 1原有</p>
<p>　　状态机图　　　　描述事件如何改变对象生命周期　　　　　　　　　　UML 1原有</p>
<p>　　顺序图　　　　　描述对象之间的交互，重点在强调顺序　　　　　　　UML 1原有</p>
<p>　　通信图　　　　　描述对象之间的交互，重点在于连接　　　　　　　　UML 1中的协作图</p>
<p>　　定时图　　　　　描述对象之间的交互，重点在于定时　　　　　　　　UML 2.0 新增</p>
<p>　　交互概观图　　　是一种顺序图与活动图的混合　　　　　　　　　　　UML 2.0新增</p>
<p>　　附：开发过程与图的对应关系</p>
<p>　　<img alt="" src="http://dev.yesky.com/imagelist/2009/077/dry5f6dc92p8.jpg" width="684" height="462" /></p>
<br />
<br /><img src ="http://www.blogjava.net/hulizhong/aggbug/265779.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hulizhong/" target="_blank">二胡</a> 2009-04-15 16:12 <a href="http://www.blogjava.net/hulizhong/archive/2009/04/15/265779.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>UML手册</title><link>http://www.blogjava.net/hulizhong/archive/2009/03/10/258873.html</link><dc:creator>二胡</dc:creator><author>二胡</author><pubDate>Tue, 10 Mar 2009 10:08:00 GMT</pubDate><guid>http://www.blogjava.net/hulizhong/archive/2009/03/10/258873.html</guid><wfw:comment>http://www.blogjava.net/hulizhong/comments/258873.html</wfw:comment><comments>http://www.blogjava.net/hulizhong/archive/2009/03/10/258873.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/hulizhong/comments/commentRss/258873.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hulizhong/services/trackbacks/258873.html</trackback:ping><description><![CDATA[转 http://www.blogjava.net/liuwentao253/archive/2006/11/18/81930.html<br />
<br />
<div class="postText">
<p>目录&nbsp; ：<br />
<br />
<img src="http://www.dlog.cn/uploads/diary/200611/18132816416.jpg"  alt="" /><br />
<br />
UML视图和图<br />
<br />
<img src="http://www.dlog.cn/uploads/diary/200611/18134429342.jpg"  alt="" /><br />
<br />
一&nbsp; ：静态视图 <br />
<br />
静态视图 的主要组成部分是 类和关系 ，它显示为类图 因为它不描述时间相关的行为，因而是静态的， 关系包括 ：关联，继承 和各种依赖，依赖包括实现和使用。类间的关系绘成连接类的路径，不同种类的关系由线上的结构和路径 或端点上的修饰来区分。<br />
<br />
例子 ：<br />
<br />
票房应用的类图<br />
<br />
<img src="http://www.dlog.cn/uploads/diary/200611/18144307484.jpg"  alt="" /><br />
<br />
<br />
图例 ：<br />
<img src="http://www.dlog.cn/uploads/diary/200611/18151256794.jpg"  alt="" /><br />
<br />
二 ：用例图 <br />
<br />
用例作为交互视图中的协作来实现的。 主要从活动者的角度考虑。<br />
<br />
<img src="http://www.dlog.cn/uploads/diary/200611/18155922034.jpg"  alt="" /><br />
<br />
三 ： 交互视图 <br />
<br />
1 ：顺序图 </p>
<p><img src="http://www.dlog.cn/uploads/diary/200611/18161445307.jpg"  alt="" /> <br />
<br />
2 ：协作图 <br />
<br />
<img src="http://www.dlog.cn/uploads/diary/200611/18162811349.jpg"  alt="" /><br />
<br />
<br />
四 ：状态机视图<br />
<br />
状态机显示为状态图 <br />
<br />
<img src="http://www.dlog.cn/uploads/diary/200611/18164147115.jpg"  alt="" /><br />
<br />
五 ：活动视图<br />
<br />
横条表示控制的分叉河连接<br />
<br />
<img src="http://www.dlog.cn/uploads/diary/200611/18165754750.jpg"  alt="" /><br />
<br />
六 ：物理视图 <br />
<br />
有两种物理视图 ：实现视图 和 配置视图<br />
<br />
1 ：实现视图 <br />
<br />
实现视图显示为构件图<br />
<br />
接口显示为具有哦名称的圆，即相关的服务集 ，连接构件和接口的实线表示构件提供接口所列举的服务。从构件至接口的虚线表明构件需要接口所提供的服务<br />
<br />
<img src="http://www.dlog.cn/uploads/diary/200611/18171946990.jpg"  alt="" /><br />
<br />
<br />
2 ：配置视图 <br />
<br />
配置视图表达了运行时断 构件实力在结点实例中的分布，结点是运行资源，如计算机，设备或内存，该视图允许分布式的结果和资源分配被评估，下面图中展示了系统中结点的种类和结点所拥有构件的种类，节电显示为方块。<br />
<br />
<img src="http://www.dlog.cn/uploads/diary/200611/18173316608.jpg"  alt="" /><br />
<br />
下图 是 一个实例级别的配置图 <br />
<br />
<img src="http://www.dlog.cn/uploads/diary/200611/18174112935.jpg"  alt="" /><br />
<br />
七 ：模型管理视图 <br />
<br />
<img src="http://www.dlog.cn/uploads/diary/200611/18175238529.jpg"  alt="" /><br />
<br />
最后 来几张图 <br />
<br />
<img src="http://www.dlog.cn/uploads/diary/200611/18183331749.jpg"  alt="" /><br />
<br />
<img src="http://www.dlog.cn/uploads/diary/200611/18183644006.jpg"  alt="" /><br />
</p>
</div>
<div class="postfoot"></div><img src ="http://www.blogjava.net/hulizhong/aggbug/258873.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hulizhong/" target="_blank">二胡</a> 2009-03-10 18:08 <a href="http://www.blogjava.net/hulizhong/archive/2009/03/10/258873.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>UML 图 之 一 ： 类图</title><link>http://www.blogjava.net/hulizhong/archive/2009/03/10/258872.html</link><dc:creator>二胡</dc:creator><author>二胡</author><pubDate>Tue, 10 Mar 2009 10:06:00 GMT</pubDate><guid>http://www.blogjava.net/hulizhong/archive/2009/03/10/258872.html</guid><wfw:comment>http://www.blogjava.net/hulizhong/comments/258872.html</wfw:comment><comments>http://www.blogjava.net/hulizhong/archive/2009/03/10/258872.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/hulizhong/comments/commentRss/258872.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hulizhong/services/trackbacks/258872.html</trackback:ping><description><![CDATA[转 http://www.blogjava.net/liuwentao253/archive/2007/09/03/142245.html<br />
<div class="postTitle"><a id="viewpost1_TitleUrl" href="http://www.blogjava.net/liuwentao253/archive/2007/09/03/142245.html">UML 图 之 一 ： 类图</a> </div>
<div class="postText">
<p><img height="1073" alt="" src="http://www.blogjava.net/images/blogjava_net/liuwentao253/class7.jpg" width="847" border="0" /><br />
<img height="1123" alt="" src="http://www.blogjava.net/images/blogjava_net/liuwentao253/class8.jpg" width="850" border="0" /><br />
<br />
类图中的关系 ：<br />
<br />
1 ：一般化（Generalization ）关系 <br />
<br />
<img height="519" alt="" src="http://www.blogjava.net/images/blogjava_net/liuwentao253/class1.jpg" width="783" border="0" /><br />
<br />
2 ：关联( Association )关系 </p>
<p><img height="1033" alt="" src="http://www.blogjava.net/images/blogjava_net/liuwentao253/class2.jpg" width="791" border="0" /><br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.1 :&nbsp; 聚合（Aggregation )关系<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <img height="571" alt="" src="http://www.blogjava.net/images/blogjava_net/liuwentao253/class3.jpg" width="776" border="0" /><br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.2 : 合成(Composition)关系<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<img height="574" alt="" src="http://www.blogjava.net/images/blogjava_net/liuwentao253/class4.jpg" width="789" border="0" /><br />
<br />
3 :&nbsp; 依赖 ( Dependency )关系<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<img height="988" alt="" src="http://www.blogjava.net/images/blogjava_net/liuwentao253/class5.jpg" width="812" border="0" /></p>
</div>
<div class="postfoot"></div><img src ="http://www.blogjava.net/hulizhong/aggbug/258872.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hulizhong/" target="_blank">二胡</a> 2009-03-10 18:06 <a href="http://www.blogjava.net/hulizhong/archive/2009/03/10/258872.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>类与类关系的UML图与代码表现</title><link>http://www.blogjava.net/hulizhong/archive/2009/03/10/258871.html</link><dc:creator>二胡</dc:creator><author>二胡</author><pubDate>Tue, 10 Mar 2009 09:55:00 GMT</pubDate><guid>http://www.blogjava.net/hulizhong/archive/2009/03/10/258871.html</guid><wfw:comment>http://www.blogjava.net/hulizhong/comments/258871.html</wfw:comment><comments>http://www.blogjava.net/hulizhong/archive/2009/03/10/258871.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/hulizhong/comments/commentRss/258871.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hulizhong/services/trackbacks/258871.html</trackback:ping><description><![CDATA[<br />
转 http://www.blogjava.net/liuwentao253/archive/2008/08/01/219416.html<br />
一&nbsp; ： <br />
<img alt="" src="http://www.blogjava.net/images/blogjava_net/liuwentao253/2008-12-09-006.jpg" border="0" /><br />
<br />
二 ： <br />
<br />
<img alt="" src="http://www.blogjava.net/images/blogjava_net/liuwentao253/2008-12-09-007.jpg" border="0" /><br />
<br />
<img alt="" src="http://www.blogjava.net/images/blogjava_net/liuwentao253/2008-12-09-004.jpg" border="0" /><br />
<br />
三 ： <br />
<br />
<img alt="" src="http://www.blogjava.net/images/blogjava_net/liuwentao253/2008-12-09-005.jpg" border="0" /><br />
<br />
四 ：<br />
<br />
<img alt="" src="http://www.blogjava.net/images/blogjava_net/liuwentao253/2008-12-09-003.jpg" border="0" /><br />
<br />
五 ： <br />
<br />
<img alt="" src="http://www.blogjava.net/images/blogjava_net/liuwentao253/2008-12-09-002.jpg" border="0" /><br />
<br />
<br />
类与类之间的关系对于理解面向对象具有很重要的作用，存在以下关系:<br />
(1)泛化(Generalization)&nbsp;&nbsp; ：狗与动物&nbsp; (空箭头)<br />
(2)关联(Association)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ：公司与员工有特定的某种关系 (实线)<br />
(3)依赖(Dependency)&nbsp;&nbsp;&nbsp; ：人依赖螺丝刀 (虚线箭头)<br />
(4)聚合(Aggregation)&nbsp;&nbsp;&nbsp;&nbsp; ： 电脑和CPU，主板 (菱形空间头)<br />
<br />
<br />
<img alt="" src="http://www.blogjava.net/images/blogjava_net/liuwentao253/2008-12-03_4.jpg" border="0" /><br />
<br />
<br />
<img alt="" src="http://www.blogjava.net/images/blogjava_net/liuwentao253/2008-12-03_5.jpg" border="0" /><br />
<br />
详细展开&nbsp; ： <br />
一 .泛化(Generalization)<br />
&nbsp;表示<strong><u>类与类之间的继承关系</u></strong>，<strong><u>接口与接口之间的继承关系</u></strong>，<u><strong>或类对接口的实现关系</strong></u>。<br />
&nbsp;一般泛化的关系是从子类指向父类的：<br />
&nbsp;父类 父类实例＝new 子类()<br />
<br />
<br />
<img height="172" alt="" src="http://www.blogjava.net/images/blogjava_net/liuwentao253/um1.jpg" width="259" border="0" /><br />
<br />
<div style="border-right: rgb(204,204,204) 1px solid; padding-right: 5px; border-top: rgb(204,204,204) 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: rgb(204,204,204) 1px solid; width: 98%; padding-top: 4px; border-bottom: rgb(204,204,204) 1px solid; background-color: rgb(238,238,238)"><span style="color: rgb(0,128,128)">1</span><img id="Codehighlighter1_0_13_Open_Image" onclick="this.style.display='none'; Codehighlighter1_0_13_Open_Text.style.display='none'; Codehighlighter1_0_13_Closed_Image.style.display='inline'; Codehighlighter1_0_13_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_0_13_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_0_13_Closed_Text.style.display='none'; Codehighlighter1_0_13_Open_Image.style.display='inline'; Codehighlighter1_0_13_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ContractedBlock.gif" align="top" /><span id="Codehighlighter1_0_13_Closed_Text" style="border-right: rgb(128,128,128) 1px solid; border-top: rgb(128,128,128) 1px solid; display: none; border-left: rgb(128,128,128) 1px solid; border-bottom: rgb(128,128,128) 1px solid; background-color: rgb(255,255,255)">/**&nbsp;*/</span><span id="Codehighlighter1_0_13_Open_Text"><span style="color: rgb(0,128,0)">/**</span><span style="color: rgb(0,128,0)"><br />
</span><span style="color: rgb(0,128,128)">2</span><span style="color: rgb(0,128,0)"><img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top" />*&nbsp;一个测试类<br />
</span><span style="color: rgb(0,128,128)">3</span><span style="color: rgb(0,128,0)"><img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" /></span><span style="color: rgb(0,128,0)">*/</span></span><span style="color: rgb(0,0,0)"><br />
</span><span style="color: rgb(0,128,128)">4</span><span style="color: rgb(0,0,0)"><img id="Codehighlighter1_32_137_Open_Image" onclick="this.style.display='none'; Codehighlighter1_32_137_Open_Text.style.display='none'; Codehighlighter1_32_137_Closed_Image.style.display='inline'; Codehighlighter1_32_137_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_32_137_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_32_137_Closed_Text.style.display='none'; Codehighlighter1_32_137_Open_Image.style.display='inline'; Codehighlighter1_32_137_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)">&nbsp;</span><span style="color: rgb(0,0,255)">class</span><span style="color: rgb(0,0,0)">&nbsp;Demo</span><span id="Codehighlighter1_32_137_Closed_Text" style="border-right: rgb(128,128,128) 1px solid; border-top: rgb(128,128,128) 1px solid; display: none; border-left: rgb(128,128,128) 1px solid; border-bottom: rgb(128,128,128) 1px solid; background-color: rgb(255,255,255)"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_32_137_Open_Text"><span style="color: rgb(0,0,0)">{&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: rgb(0,128,128)">5</span><span style="color: rgb(0,0,0)"><img id="Codehighlighter1_61_131_Open_Image" onclick="this.style.display='none'; Codehighlighter1_61_131_Open_Text.style.display='none'; Codehighlighter1_61_131_Closed_Image.style.display='inline'; Codehighlighter1_61_131_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_61_131_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_61_131_Closed_Text.style.display='none'; Codehighlighter1_61_131_Open_Image.style.display='inline'; Codehighlighter1_61_131_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)">&nbsp;</span><span style="color: rgb(0,0,255)">void</span><span style="color: rgb(0,0,0)">&nbsp;test()&nbsp;</span><span id="Codehighlighter1_61_131_Closed_Text" style="border-right: rgb(128,128,128) 1px solid; border-top: rgb(128,128,128) 1px solid; display: none; border-left: rgb(128,128,128) 1px solid; border-bottom: rgb(128,128,128) 1px solid; background-color: rgb(255,255,255)"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_61_131_Open_Text"><span style="color: rgb(0,0,0)">{<br />
</span><span style="color: rgb(0,128,128)">6</span><span style="color: rgb(0,0,0)"><img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,128,0)">//</span><span style="color: rgb(0,128,0)">老虎的实例&nbsp;也属于动物类型&nbsp;</span><span style="color: rgb(0,128,0)"><br />
</span><span style="color: rgb(0,128,128)">7</span><span style="color: rgb(0,128,0)"><img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Animal&nbsp;animal&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,255)">new</span><span style="color: rgb(0,0,0)">&nbsp;Tiger();&nbsp;&nbsp;<br />
</span><span style="color: rgb(0,128,128)">8</span><span style="color: rgb(0,0,0)"><img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: rgb(0,128,128)">9</span><span style="color: rgb(0,0,0)"><img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="color: rgb(0,0,0)">&nbsp;</span></div>
<br />
<br />
<br />
<div style="border-right: rgb(204,204,204) 1px solid; padding-right: 5px; border-top: rgb(204,204,204) 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: rgb(204,204,204) 1px solid; width: 98%; padding-top: 4px; border-bottom: rgb(204,204,204) 1px solid; background-color: rgb(238,238,238)"><span style="color: rgb(0,128,128)">1</span><img id="Codehighlighter1_0_12_Open_Image" onclick="this.style.display='none'; Codehighlighter1_0_12_Open_Text.style.display='none'; Codehighlighter1_0_12_Closed_Image.style.display='inline'; Codehighlighter1_0_12_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_0_12_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_0_12_Closed_Text.style.display='none'; Codehighlighter1_0_12_Open_Image.style.display='inline'; Codehighlighter1_0_12_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ContractedBlock.gif" align="top" /><span id="Codehighlighter1_0_12_Closed_Text" style="border-right: rgb(128,128,128) 1px solid; border-top: rgb(128,128,128) 1px solid; display: none; border-left: rgb(128,128,128) 1px solid; border-bottom: rgb(128,128,128) 1px solid; background-color: rgb(255,255,255)">/**&nbsp;*/</span><span id="Codehighlighter1_0_12_Open_Text"><span style="color: rgb(0,128,0)">/**</span><span style="color: rgb(0,128,0)"><br />
</span><span style="color: rgb(0,128,128)">2</span><span style="color: rgb(0,128,0)"><img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top" />*&nbsp;&nbsp;动物类<br />
</span><span style="color: rgb(0,128,128)">3</span><span style="color: rgb(0,128,0)"><img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" /></span><span style="color: rgb(0,128,0)">*/</span></span><span style="color: rgb(0,0,0)"><br />
</span><span style="color: rgb(0,128,128)">4</span><span style="color: rgb(0,0,0)"><img id="Codehighlighter1_33_36_Open_Image" onclick="this.style.display='none'; Codehighlighter1_33_36_Open_Text.style.display='none'; Codehighlighter1_33_36_Closed_Image.style.display='inline'; Codehighlighter1_33_36_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_33_36_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_33_36_Closed_Text.style.display='none'; Codehighlighter1_33_36_Open_Image.style.display='inline'; Codehighlighter1_33_36_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)">&nbsp;</span><span style="color: rgb(0,0,255)">class</span><span style="color: rgb(0,0,0)">&nbsp;Animal</span><span id="Codehighlighter1_33_36_Closed_Text" style="border-right: rgb(128,128,128) 1px solid; border-top: rgb(128,128,128) 1px solid; display: none; border-left: rgb(128,128,128) 1px solid; border-bottom: rgb(128,128,128) 1px solid; background-color: rgb(255,255,255)"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_33_36_Open_Text"><span style="color: rgb(0,0,0)">{<br />
</span><span style="color: rgb(0,128,128)">5</span><span style="color: rgb(0,0,0)"><img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top" /><br />
</span><span style="color: rgb(0,128,128)">6</span><span style="color: rgb(0,0,0)"><img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;</span></div>
<br />
<br />
<div style="border-right: rgb(204,204,204) 1px solid; padding-right: 5px; border-top: rgb(204,204,204) 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: rgb(204,204,204) 1px solid; width: 98%; padding-top: 4px; border-bottom: rgb(204,204,204) 1px solid; background-color: rgb(238,238,238)"><span style="color: rgb(0,128,128)">1</span><img id="Codehighlighter1_0_12_Open_Image" onclick="this.style.display='none'; Codehighlighter1_0_12_Open_Text.style.display='none'; Codehighlighter1_0_12_Closed_Image.style.display='inline'; Codehighlighter1_0_12_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_0_12_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_0_12_Closed_Text.style.display='none'; Codehighlighter1_0_12_Open_Image.style.display='inline'; Codehighlighter1_0_12_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ContractedBlock.gif" align="top" /><span id="Codehighlighter1_0_12_Closed_Text" style="border-right: rgb(128,128,128) 1px solid; border-top: rgb(128,128,128) 1px solid; display: none; border-left: rgb(128,128,128) 1px solid; border-bottom: rgb(128,128,128) 1px solid; background-color: rgb(255,255,255)">/**&nbsp;*/</span><span id="Codehighlighter1_0_12_Open_Text"><span style="color: rgb(0,128,0)">/**</span><span style="color: rgb(0,128,0)"><br />
</span><span style="color: rgb(0,128,128)">2</span><span style="color: rgb(0,128,0)"><img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top" />*&nbsp;老虎类&nbsp;<br />
</span><span style="color: rgb(0,128,128)">3</span><span style="color: rgb(0,128,0)"><img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" /></span><span style="color: rgb(0,128,0)">*/</span></span><span style="color: rgb(0,0,0)"><br />
</span><span style="color: rgb(0,128,128)">4</span><span style="color: rgb(0,0,0)"><img id="Codehighlighter1_47_50_Open_Image" onclick="this.style.display='none'; Codehighlighter1_47_50_Open_Text.style.display='none'; Codehighlighter1_47_50_Closed_Image.style.display='inline'; Codehighlighter1_47_50_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_47_50_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_47_50_Closed_Text.style.display='none'; Codehighlighter1_47_50_Open_Image.style.display='inline'; Codehighlighter1_47_50_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)">&nbsp;</span><span style="color: rgb(0,0,255)">class</span><span style="color: rgb(0,0,0)">&nbsp;Tiger&nbsp;</span><span style="color: rgb(0,0,255)">extends</span><span style="color: rgb(0,0,0)">&nbsp;Animal</span><span id="Codehighlighter1_47_50_Closed_Text" style="border-right: rgb(128,128,128) 1px solid; border-top: rgb(128,128,128) 1px solid; display: none; border-left: rgb(128,128,128) 1px solid; border-bottom: rgb(128,128,128) 1px solid; background-color: rgb(255,255,255)"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_47_50_Open_Text"><span style="color: rgb(0,0,0)">{<br />
</span><span style="color: rgb(0,128,128)">5</span><span style="color: rgb(0,0,0)"><img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top" /><br />
</span><span style="color: rgb(0,128,128)">6</span><span style="color: rgb(0,0,0)"><img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="color: rgb(0,0,0)">&nbsp;&nbsp;</span></div>
<br />
<br />
二 .依赖(Dependency)<br />
<br />
对于两个相对独立的对象，当一个对象（螺丝刀）负责构造另一个对象(人)的实例，或者一个对象(人)依赖另一个对象（螺丝刀）的服务时，这两个对象之间主要体现为依赖关系。<br />
<br />
下面这个例子显然属于后者 ：人要做一个拧螺丝的动作，他就要依赖于 螺丝刀对象，因为只有螺丝刀对象才提供拧螺丝的服务。 <br />
<br />
<img height="82" alt="" src="http://www.blogjava.net/images/blogjava_net/liuwentao253/um2.jpg" width="272" border="0" /><br />
<br />
<div style="border-right: rgb(204,204,204) 1px solid; padding-right: 5px; border-top: rgb(204,204,204) 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: rgb(204,204,204) 1px solid; width: 98%; padding-top: 4px; border-bottom: rgb(204,204,204) 1px solid; background-color: rgb(238,238,238)"><span style="color: rgb(0,128,128)">&nbsp;1</span><img id="Codehighlighter1_0_21_Open_Image" onclick="this.style.display='none'; Codehighlighter1_0_21_Open_Text.style.display='none'; Codehighlighter1_0_21_Closed_Image.style.display='inline'; Codehighlighter1_0_21_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_0_21_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_0_21_Closed_Text.style.display='none'; Codehighlighter1_0_21_Open_Image.style.display='inline'; Codehighlighter1_0_21_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ContractedBlock.gif" align="top" /><span id="Codehighlighter1_0_21_Closed_Text" style="border-right: rgb(128,128,128) 1px solid; border-top: rgb(128,128,128) 1px solid; display: none; border-left: rgb(128,128,128) 1px solid; border-bottom: rgb(128,128,128) 1px solid; background-color: rgb(255,255,255)">/**&nbsp;*/</span><span id="Codehighlighter1_0_21_Open_Text"><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><span style="color: rgb(0,128,0)"><img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;*&nbsp;说明&nbsp;：人&nbsp;这个&nbsp;类&nbsp;<br />
</span><span style="color: rgb(0,128,128)">&nbsp;3</span><span style="color: rgb(0,128,0)"><img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />&nbsp;</span><span style="color: rgb(0,128,0)">*/</span></span><span style="color: rgb(0,0,0)"><br />
</span><span style="color: rgb(0,128,128)">&nbsp;4</span><span style="color: rgb(0,0,0)"><img id="Codehighlighter1_43_245_Open_Image" onclick="this.style.display='none'; Codehighlighter1_43_245_Open_Text.style.display='none'; Codehighlighter1_43_245_Closed_Image.style.display='inline'; Codehighlighter1_43_245_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_43_245_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_43_245_Closed_Text.style.display='none'; Codehighlighter1_43_245_Open_Image.style.display='inline'; Codehighlighter1_43_245_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)">&nbsp;</span><span style="color: rgb(0,0,255)">class</span><span style="color: rgb(0,0,0)">&nbsp;Person&nbsp;</span><span id="Codehighlighter1_43_245_Closed_Text" style="border-right: rgb(128,128,128) 1px solid; border-top: rgb(128,128,128) 1px solid; display: none; border-left: rgb(128,128,128) 1px solid; border-bottom: rgb(128,128,128) 1px solid; background-color: rgb(255,255,255)"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_43_245_Open_Text"><span style="color: rgb(0,0,0)">{<br />
</span><span style="color: rgb(0,128,128)">&nbsp;5</span><span style="color: rgb(0,0,0)"><img id="Codehighlighter1_49_127_Open_Image" onclick="this.style.display='none'; Codehighlighter1_49_127_Open_Text.style.display='none'; Codehighlighter1_49_127_Closed_Image.style.display='inline'; Codehighlighter1_49_127_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_49_127_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_49_127_Closed_Text.style.display='none'; Codehighlighter1_49_127_Open_Image.style.display='inline'; Codehighlighter1_49_127_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_49_127_Closed_Text" style="border-right: rgb(128,128,128) 1px solid; border-top: rgb(128,128,128) 1px solid; display: none; border-left: rgb(128,128,128) 1px solid; border-bottom: rgb(128,128,128) 1px solid; background-color: rgb(255,255,255)">/**&nbsp;*/</span><span id="Codehighlighter1_49_127_Open_Text"><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;6</span><span style="color: rgb(0,128,0)"><img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;人拥有的一个&nbsp;&nbsp;拧螺丝&nbsp;&nbsp;的&nbsp;&nbsp;动作&nbsp;依赖于螺丝刀这个类<br />
</span><span style="color: rgb(0,128,128)">&nbsp;7</span><span style="color: rgb(0,128,0)"><img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span style="color: rgb(128,128,128)">@param</span><span style="color: rgb(0,128,0)">&nbsp;screwdriver&nbsp;：螺丝刀类<br />
</span><span style="color: rgb(0,128,128)">&nbsp;8</span><span style="color: rgb(0,128,0)"><img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,128,0)">*/</span></span><span style="color: rgb(0,0,0)"><br />
</span><span style="color: rgb(0,128,128)">&nbsp;9</span><span style="color: rgb(0,0,0)"><img id="Codehighlighter1_176_241_Open_Image" onclick="this.style.display='none'; Codehighlighter1_176_241_Open_Text.style.display='none'; Codehighlighter1_176_241_Closed_Image.style.display='inline'; Codehighlighter1_176_241_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_176_241_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_176_241_Closed_Text.style.display='none'; Codehighlighter1_176_241_Open_Image.style.display='inline'; Codehighlighter1_176_241_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)">&nbsp;</span><span style="color: rgb(0,0,255)">void</span><span style="color: rgb(0,0,0)">&nbsp;screw(Screwdriver&nbsp;screwdriver)</span><span id="Codehighlighter1_176_241_Closed_Text" style="border-right: rgb(128,128,128) 1px solid; border-top: rgb(128,128,128) 1px solid; display: none; border-left: rgb(128,128,128) 1px solid; border-bottom: rgb(128,128,128) 1px solid; background-color: rgb(255,255,255)"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_176_241_Open_Text"><span style="color: rgb(0,0,0)">{&nbsp;<br />
</span><span style="color: rgb(0,128,128)">10</span><span style="color: rgb(0,0,0)"><img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,128,0)">//</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)">11</span><span style="color: rgb(0,128,0)"><img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;screwdriver.screw();&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: rgb(0,128,128)">12</span><span style="color: rgb(0,0,0)"><img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: rgb(0,0,0)">&nbsp;&nbsp;<br />
</span><span style="color: rgb(0,128,128)">13</span><span style="color: rgb(0,0,0)"><img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span></div>
<br />
<br />
三 .关联(Association)<br />
对于两个相对独立的对象，当一个对象的实例与另一个对象的一些特定实例存在固定的对应关系时，这两个对象之间为关联关系。<br />
关联关系是使用实例变量来实现<br />
比如客户和订单，每个订单对应特定的客户，每个客户对应一些特定的订单；再例如公司和员工，每个公司对应一些特定的员工，每个员工对应一特定的公司<br />
<br />
<img height="57" alt="" src="http://www.blogjava.net/images/blogjava_net/liuwentao253/um4.jpg" width="291" border="0" /><br />
<br />
<br />
<div style="border-right: rgb(204,204,204) 1px solid; padding-right: 5px; border-top: rgb(204,204,204) 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: rgb(204,204,204) 1px solid; width: 98%; padding-top: 4px; border-bottom: rgb(204,204,204) 1px solid; background-color: rgb(238,238,238)"><span style="color: rgb(0,128,128)">&nbsp;1</span><img id="Codehighlighter1_0_12_Open_Image" onclick="this.style.display='none'; Codehighlighter1_0_12_Open_Text.style.display='none'; Codehighlighter1_0_12_Closed_Image.style.display='inline'; Codehighlighter1_0_12_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_0_12_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_0_12_Closed_Text.style.display='none'; Codehighlighter1_0_12_Open_Image.style.display='inline'; Codehighlighter1_0_12_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ContractedBlock.gif" align="top" /><span id="Codehighlighter1_0_12_Closed_Text" style="border-right: rgb(128,128,128) 1px solid; border-top: rgb(128,128,128) 1px solid; display: none; border-left: rgb(128,128,128) 1px solid; border-bottom: rgb(128,128,128) 1px solid; background-color: rgb(255,255,255)">/**&nbsp;*/</span><span id="Codehighlighter1_0_12_Open_Text"><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><span style="color: rgb(0,128,0)"><img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;*&nbsp;公司<br />
</span><span style="color: rgb(0,128,128)">&nbsp;3</span><span style="color: rgb(0,128,0)"><img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />&nbsp;</span><span style="color: rgb(0,128,0)">*/</span></span><span style="color: rgb(0,0,0)"><br />
</span><span style="color: rgb(0,128,128)">&nbsp;4</span><span style="color: rgb(0,0,0)"><img id="Codehighlighter1_34_358_Open_Image" onclick="this.style.display='none'; Codehighlighter1_34_358_Open_Text.style.display='none'; Codehighlighter1_34_358_Closed_Image.style.display='inline'; Codehighlighter1_34_358_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_34_358_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_34_358_Closed_Text.style.display='none'; Codehighlighter1_34_358_Open_Image.style.display='inline'; Codehighlighter1_34_358_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)">&nbsp;</span><span style="color: rgb(0,0,255)">class</span><span style="color: rgb(0,0,0)">&nbsp;Company</span><span id="Codehighlighter1_34_358_Closed_Text" style="border-right: rgb(128,128,128) 1px solid; border-top: rgb(128,128,128) 1px solid; display: none; border-left: rgb(128,128,128) 1px solid; border-bottom: rgb(128,128,128) 1px solid; background-color: rgb(255,255,255)"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_34_358_Open_Text"><span style="color: rgb(0,0,0)">{&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: rgb(0,128,128)">&nbsp;5</span><span style="color: rgb(0,0,0)"><img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,128,0)">//</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;6</span><span style="color: rgb(0,128,0)"><img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,0,255)">private</span><span style="color: rgb(0,0,0)">&nbsp;Employee&nbsp;employee;<br />
</span><span style="color: rgb(0,128,128)">&nbsp;7</span><span style="color: rgb(0,0,0)"><img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top" /><br />
</span><span style="color: rgb(0,128,128)">&nbsp;8</span><span style="color: rgb(0,0,0)"><img id="Codehighlighter1_84_107_Open_Image" onclick="this.style.display='none'; Codehighlighter1_84_107_Open_Text.style.display='none'; Codehighlighter1_84_107_Closed_Image.style.display='inline'; Codehighlighter1_84_107_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_84_107_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_84_107_Closed_Text.style.display='none'; Codehighlighter1_84_107_Open_Image.style.display='inline'; Codehighlighter1_84_107_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_84_107_Closed_Text" style="border-right: rgb(128,128,128) 1px solid; border-top: rgb(128,128,128) 1px solid; display: none; border-left: rgb(128,128,128) 1px solid; border-bottom: rgb(128,128,128) 1px solid; background-color: rgb(255,255,255)">/**&nbsp;*/</span><span id="Codehighlighter1_84_107_Open_Text"><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;9</span><span style="color: rgb(0,128,0)"><img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;公司运作<br />
</span><span style="color: rgb(0,128,128)">10</span><span style="color: rgb(0,128,0)"><img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,128,0)">*/</span></span><span style="color: rgb(0,0,0)"><br />
</span><span style="color: rgb(0,128,128)">11</span><span style="color: rgb(0,0,0)"><img id="Codehighlighter1_130_177_Open_Image" onclick="this.style.display='none'; Codehighlighter1_130_177_Open_Text.style.display='none'; Codehighlighter1_130_177_Closed_Image.style.display='inline'; Codehighlighter1_130_177_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_130_177_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_130_177_Closed_Text.style.display='none'; Codehighlighter1_130_177_Open_Image.style.display='inline'; Codehighlighter1_130_177_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)">&nbsp;</span><span style="color: rgb(0,0,255)">void</span><span style="color: rgb(0,0,0)">&nbsp;run()</span><span id="Codehighlighter1_130_177_Closed_Text" style="border-right: rgb(128,128,128) 1px solid; border-top: rgb(128,128,128) 1px solid; display: none; border-left: rgb(128,128,128) 1px solid; border-bottom: rgb(128,128,128) 1px solid; background-color: rgb(255,255,255)"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_130_177_Open_Text"><span style="color: rgb(0,0,0)">{&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: rgb(0,128,128)">12</span><span style="color: rgb(0,0,0)"><img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;employee.startWorking();&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: rgb(0,128,128)">13</span><span style="color: rgb(0,0,0)"><img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: rgb(0,0,0)"><br />
</span><span style="color: rgb(0,128,128)">14</span><span style="color: rgb(0,0,0)"><img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: rgb(0,128,128)">15</span><span style="color: rgb(0,0,0)"><img id="Codehighlighter1_217_256_Open_Image" onclick="this.style.display='none'; Codehighlighter1_217_256_Open_Text.style.display='none'; Codehighlighter1_217_256_Closed_Image.style.display='inline'; Codehighlighter1_217_256_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_217_256_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_217_256_Closed_Text.style.display='none'; Codehighlighter1_217_256_Open_Image.style.display='inline'; Codehighlighter1_217_256_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)">&nbsp;Employee&nbsp;getEmployee()</span><span id="Codehighlighter1_217_256_Closed_Text" style="border-right: rgb(128,128,128) 1px solid; border-top: rgb(128,128,128) 1px solid; display: none; border-left: rgb(128,128,128) 1px solid; border-bottom: rgb(128,128,128) 1px solid; background-color: rgb(255,255,255)"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_217_256_Open_Text"><span style="color: rgb(0,0,0)">{&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: rgb(0,128,128)">16</span><span style="color: rgb(0,0,0)"><img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top" />&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;employee;&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: rgb(0,128,128)">17</span><span style="color: rgb(0,0,0)"><img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: rgb(0,128,128)">18</span><span style="color: rgb(0,0,0)"><img id="Codehighlighter1_308_354_Open_Image" onclick="this.style.display='none'; Codehighlighter1_308_354_Open_Text.style.display='none'; Codehighlighter1_308_354_Closed_Image.style.display='inline'; Codehighlighter1_308_354_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_308_354_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_308_354_Closed_Text.style.display='none'; Codehighlighter1_308_354_Open_Image.style.display='inline'; Codehighlighter1_308_354_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)">&nbsp;</span><span style="color: rgb(0,0,255)">void</span><span style="color: rgb(0,0,0)">&nbsp;setEmployee(Employee&nbsp;employee)</span><span id="Codehighlighter1_308_354_Closed_Text" style="border-right: rgb(128,128,128) 1px solid; border-top: rgb(128,128,128) 1px solid; display: none; border-left: rgb(128,128,128) 1px solid; border-bottom: rgb(128,128,128) 1px solid; background-color: rgb(255,255,255)"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_308_354_Open_Text"><span style="color: rgb(0,0,0)">{&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: rgb(0,128,128)">19</span><span style="color: rgb(0,0,0)"><img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,0,255)">this</span><span style="color: rgb(0,0,0)">.employee</span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)">employee;&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: rgb(0,128,128)">20</span><span style="color: rgb(0,0,0)"><img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: rgb(0,0,0)">&nbsp;&nbsp;<br />
</span><span style="color: rgb(0,128,128)">21</span><span style="color: rgb(0,0,0)"><img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="color: rgb(0,0,0)">&nbsp;</span></div>
<br />
四 ： 聚合（Aggregation）<br />
当对象A被加入到对象B中，成为对象B的组成部分时，对象B和对象A之间为聚集关系。聚合是关联关系的一种，是较强的关联关系，强调的是整体与部分之间的关系。<br />
[关联与聚合的区别]<br />
(1)关联关系所涉及的两个对象是处在同一个层次上的。比如人和自行车就是一种关联关系，而不是聚合关系，因为人不是由自行车组成的。<br />
聚合关系涉及的两个对象处于不平等的层次上，一个代表整体，一个代表部分。比如电脑和它的显示器、键盘、主板以及内存就是聚集关系，因为主板是电脑的组成部分。<br />
(2)对于具有聚集关系（尤其是强聚集关系）的两个对象，整体对象会制约它的组成对象的生命周期。部分类的对象不能单独存在，它的生命周期依赖于整体类的对象的生命周期，当整体消失，部分也就随之消失。比如张三的电脑被偷了，那么电脑的所有组件也不存在了，除非张三事先把一些电脑的组件（比如硬盘和内存）拆了下来。<br />
<br />
<img height="178" alt="" src="http://www.blogjava.net/images/blogjava_net/liuwentao253/um5.jpg" width="298" border="0" /><br />
<br />
<div style="border-right: rgb(204,204,204) 1px solid; padding-right: 5px; border-top: rgb(204,204,204) 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: rgb(204,204,204) 1px solid; width: 98%; padding-top: 4px; border-bottom: rgb(204,204,204) 1px solid; background-color: rgb(238,238,238)"><span style="color: rgb(0,128,128)">&nbsp;1</span><img id="Codehighlighter1_21_285_Open_Image" onclick="this.style.display='none'; Codehighlighter1_21_285_Open_Text.style.display='none'; Codehighlighter1_21_285_Closed_Image.style.display='inline'; Codehighlighter1_21_285_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_21_285_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_21_285_Closed_Text.style.display='none'; Codehighlighter1_21_285_Open_Image.style.display='inline'; Codehighlighter1_21_285_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ContractedBlock.gif" align="top" /><span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)">&nbsp;</span><span style="color: rgb(0,0,255)">class</span><span style="color: rgb(0,0,0)">&nbsp;Computer</span><span id="Codehighlighter1_21_285_Closed_Text" style="border-right: rgb(128,128,128) 1px solid; border-top: rgb(128,128,128) 1px solid; display: none; border-left: rgb(128,128,128) 1px solid; border-bottom: rgb(128,128,128) 1px solid; background-color: rgb(255,255,255)"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_21_285_Open_Text"><span style="color: rgb(0,0,0)">{&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: rgb(0,128,128)">&nbsp;2</span><span style="color: rgb(0,0,0)"><img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,0,255)">private</span><span style="color: rgb(0,0,0)">&nbsp;CPU&nbsp;cpu;&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: rgb(0,128,128)">&nbsp;3</span><span style="color: rgb(0,0,0)"><img id="Codehighlighter1_75_109_Open_Image" onclick="this.style.display='none'; Codehighlighter1_75_109_Open_Text.style.display='none'; Codehighlighter1_75_109_Closed_Image.style.display='inline'; Codehighlighter1_75_109_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_75_109_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_75_109_Closed_Text.style.display='none'; Codehighlighter1_75_109_Open_Image.style.display='inline'; Codehighlighter1_75_109_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)">&nbsp;CPU&nbsp;getCPU()</span><span id="Codehighlighter1_75_109_Closed_Text" style="border-right: rgb(128,128,128) 1px solid; border-top: rgb(128,128,128) 1px solid; display: none; border-left: rgb(128,128,128) 1px solid; border-bottom: rgb(128,128,128) 1px solid; background-color: rgb(255,255,255)"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_75_109_Open_Text"><span style="color: rgb(0,0,0)">{&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: rgb(0,128,128)">&nbsp;4</span><span style="color: rgb(0,0,0)"><img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top" />&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;cpu;&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: rgb(0,128,128)">&nbsp;5</span><span style="color: rgb(0,0,0)"><img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: rgb(0,128,128)">&nbsp;6</span><span style="color: rgb(0,0,0)"><img id="Codehighlighter1_146_182_Open_Image" onclick="this.style.display='none'; Codehighlighter1_146_182_Open_Text.style.display='none'; Codehighlighter1_146_182_Closed_Image.style.display='inline'; Codehighlighter1_146_182_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_146_182_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_146_182_Closed_Text.style.display='none'; Codehighlighter1_146_182_Open_Image.style.display='inline'; Codehighlighter1_146_182_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)">&nbsp;</span><span style="color: rgb(0,0,255)">void</span><span style="color: rgb(0,0,0)">&nbsp;setCPU(CPU&nbsp;cpu)</span><span id="Codehighlighter1_146_182_Closed_Text" style="border-right: rgb(128,128,128) 1px solid; border-top: rgb(128,128,128) 1px solid; display: none; border-left: rgb(128,128,128) 1px solid; border-bottom: rgb(128,128,128) 1px solid; background-color: rgb(255,255,255)"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_146_182_Open_Text"><span style="color: rgb(0,0,0)">{&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: rgb(0,128,128)">&nbsp;7</span><span style="color: rgb(0,0,0)"><img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,0,255)">this</span><span style="color: rgb(0,0,0)">.cpu</span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)">cpu;&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: rgb(0,128,128)">&nbsp;8</span><span style="color: rgb(0,0,0)"><img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: rgb(0,128,128)">&nbsp;9</span><span style="color: rgb(0,0,0)"><img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,128,0)">//</span><span style="color: rgb(0,128,0)">开启电脑&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,128,0)"><br />
</span><span style="color: rgb(0,128,128)">10</span><span style="color: rgb(0,128,0)"><img id="Codehighlighter1_226_279_Open_Image" onclick="this.style.display='none'; Codehighlighter1_226_279_Open_Text.style.display='none'; Codehighlighter1_226_279_Closed_Image.style.display='inline'; Codehighlighter1_226_279_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_226_279_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_226_279_Closed_Text.style.display='none'; Codehighlighter1_226_279_Open_Image.style.display='inline'; Codehighlighter1_226_279_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ContractedSubBlock.gif" align="top" /></span><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;</span><span style="color: rgb(0,0,255)">void</span><span style="color: rgb(0,0,0)">&nbsp;start()</span><span id="Codehighlighter1_226_279_Closed_Text" style="border-right: rgb(128,128,128) 1px solid; border-top: rgb(128,128,128) 1px solid; display: none; border-left: rgb(128,128,128) 1px solid; border-bottom: rgb(128,128,128) 1px solid; background-color: rgb(255,255,255)"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_226_279_Open_Text"><span style="color: rgb(0,0,0)">{&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: rgb(0,128,128)">11</span><span style="color: rgb(0,0,0)"><img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,128,0)">//</span><span style="color: rgb(0,128,0)">cpu运作&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,128,0)"><br />
</span><span style="color: rgb(0,128,128)">12</span><span style="color: rgb(0,128,0)"><img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cpu.run();&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: rgb(0,128,128)">13</span><span style="color: rgb(0,0,0)"><img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: rgb(0,128,128)">14</span><span style="color: rgb(0,0,0)"><img alt="" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="color: rgb(0,0,0)">&nbsp;&nbsp;</span></div><img src ="http://www.blogjava.net/hulizhong/aggbug/258871.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hulizhong/" target="_blank">二胡</a> 2009-03-10 17:55 <a href="http://www.blogjava.net/hulizhong/archive/2009/03/10/258871.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用例建模技巧</title><link>http://www.blogjava.net/hulizhong/archive/2009/03/10/258866.html</link><dc:creator>二胡</dc:creator><author>二胡</author><pubDate>Tue, 10 Mar 2009 09:36:00 GMT</pubDate><guid>http://www.blogjava.net/hulizhong/archive/2009/03/10/258866.html</guid><wfw:comment>http://www.blogjava.net/hulizhong/comments/258866.html</wfw:comment><comments>http://www.blogjava.net/hulizhong/archive/2009/03/10/258866.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/hulizhong/comments/commentRss/258866.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hulizhong/services/trackbacks/258866.html</trackback:ping><description><![CDATA[转 http://www.ibm.com/developerworks/cn/rational/tip-uml/index2.html<br />
<table id="content-table" cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr valign="top">
            <td width="100%">
            <table cellspacing="0" cellpadding="0" width="100%" border="0">
                <tbody>
                    <tr valign="top">
                        <td width="100%">
                        <h1>用例建模技巧</h1>
                        <p id="subtitle"><em>适合于更好的 UML 用例模型的技术</em></p>
                        <img class="display-img" height="6" alt="" src="http://www.ibm.com/i/c.gif" width="1" /></td>
                        <td class="no-print" width="192"><img height="18" alt="developerWorks" src="http://www.ibm.com/developerworks/i/dw.gif" width="192" /></td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr valign="top">
            <td width="10"><img height="1" alt="" src="http://www.ibm.com/i/c.gif" width="10" /></td>
            <td width="100%">
            <table class="no-print" cellspacing="0" cellpadding="0" width="160" align="right" border="0">
                <tbody>
                    <tr>
                        <td width="10"><img height="1" alt="" src="http://www.ibm.com/i/c.gif" width="10" /></td>
                        <td>
                        <table cellspacing="0" cellpadding="0" width="150" border="0">
                            <tbody>
                                <tr>
                                    <td class="v14-header-1-small">文档选项</td>
                                </tr>
                            </tbody>
                        </table>
                        <table class="v14-gray-table-border" cellspacing="0" cellpadding="0" border="0">
                            <tbody>
                                <tr>
                                    <td class="no-padding" width="150"><noscript></noscript><noscript></noscript>
                                    <table cellspacing="0" cellpadding="0" width="143" border="0">
                                        <script language="JavaScript" type="text/javascript">
<!-- document.write('<tr valign="top"><td width="8"><img src="//www.ibm.com/i/c.gif" width="8" height="1" alt="" /></td><td width="16"><img alt="将打印机的版面设置成横向打印模式" height="16" src="//www.ibm.com/i/v14/icons/printer.gif" width="16" vspace="3"  /></td><td width="122"><p><strong><a class="smallplainlink" href="javascript:print()">打印本页</a></strong></p></td></tr>');
//-->
</script>
                                        <tbody>
                                            <tr valign="top">
                                                <td width="8"><img height="1" alt="" src="http://www.ibm.com/i/c.gif" width="8" /></td>
                                                <td width="16"><img height="16" alt="将打印机的版面设置成横向打印模式" src="http://www.ibm.com/i/v14/icons/printer.gif" width="16" vspace="3" /></td>
                                                <td width="122">
                                                <p><strong><a class="smallplainlink" href="javascript:print()">打印本页</a></strong></p>
                                                </td>
                                            </tr>
                                            <form name="email" action="https://www.ibm.com/developerworks/secure/email-it.jsp">
                                            </form>
                                            <input type="hidden" value="本文介绍了一些提高系统用例模型质量的技巧和技术。本文改编自 Object Primer 2nd Edition 的第 6 章。" name="body" /><input type="hidden" value="用例建模技巧" name="subject" /><input type="hidden" value="cn" name="lang" /> <script language="JavaScript" type="text/javascript">
<!-- document.write('<tr valign="top"><td width="8"><img src="//www.ibm.com/i/c.gif" width="8" height="1" alt="" /></td><td width="16"><img src="//www.ibm.com/i/v14/icons/em.gif" height="16" width="16" vspace="3" alt="将此页作为电子邮件发送"  /></td><td width="122"><p><a class="smallplainlink" href="javascript:document.email.submit();"><strong>将此页作为电子邮件发送</strong></a></p></td></tr>');
//-->
</script>
                                            <tr valign="top">
                                                <td width="8"><img height="1" alt="" src="http://www.ibm.com/i/c.gif" width="8" /></td>
                                                <td width="16"><img height="16" alt="将此页作为电子邮件发送" src="http://www.ibm.com/i/v14/icons/em.gif" width="16" vspace="3" /></td>
                                                <td width="122">
                                                <p><a class="smallplainlink" href="javascript:document.email.submit();"><strong>将此页作为电子邮件发送</strong></a></p>
                                                </td>
                                            </tr>
                                        </tbody>
                                    </table>
                                    </td>
                                </tr>
                            </tbody>
                        </table>
                        <!--start RESERVED FOR FUTURE USE INCLUDE FILES--><!-- this content will be automatically generated across all content areas --><!--end RESERVED FOR FUTURE USE INCLUDE FILES--><br />
                        </td>
                    </tr>
                </tbody>
            </table>
            <p>级别： 初级</p>
            <p><a href="http://www.ibm.com/developerworks/cn/rational/tip-uml/index2.html#author">Scott W. Ambler</a> (<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#115;&#99;&#111;&#116;&#116;&#46;&#97;&#109;&#98;&#108;&#101;&#114;&#64;&#114;&#111;&#110;&#105;&#110;&#45;&#105;&#110;&#116;&#108;&#46;&#99;&#111;&#109;&#63;&#115;&#117;&#98;&#106;&#101;&#99;&#116;&#61;&#37;&#69;&#55;&#37;&#57;&#52;&#37;&#65;&#56;&#37;&#69;&#52;&#37;&#66;&#69;&#37;&#56;&#66;&#37;&#69;&#53;&#37;&#66;&#66;&#37;&#66;&#65;&#37;&#69;&#54;&#37;&#65;&#56;&#37;&#65;&#49;&#37;&#69;&#54;&#37;&#56;&#65;&#37;&#56;&#48;&#37;&#69;&#53;&#37;&#66;&#55;&#37;&#65;&#55;&#38;&#97;&#109;&#112;&#59;&#99;&#99;&#61;&#115;&#99;&#111;&#116;&#116;&#46;&#97;&#109;&#98;&#108;&#101;&#114;&#64;&#114;&#111;&#110;&#105;&#110;&#45;&#105;&#110;&#116;&#108;&#46;&#99;&#111;&#109;">scott.ambler@ronin-intl.com</a>), 总裁, Ronin International<br />
            </p>
            <p>2001 年 1 月 04 日</p>
            <blockquote>本文介绍了一些提高系统用例模型质量的技巧和技术。本文改编自 Object Primer 2nd Edition 的第 6 章。</blockquote><!--start RESERVED FOR FUTURE USE INCLUDE FILES--><!-- include java script once we verify teams wants to use this and it will work on dbcs and cyrillic characters --><!--end RESERVED FOR FUTURE USE INCLUDE FILES-->
            <p><strong>从参与者的角度并以主动语态编写用例。</strong> <br />
            应该以主动语态：&#8220;学生表明参加研习班意向&#8221;，而不是被动语态&#8220;研习班意向被学生表明&#8221;来编写用例。而且，应该从参与者的角度来编写用例。毕竟，用例的目的是理解用户如何对系统进行操作。 </p>
            <p><strong>编写方案文本，而非功能需求。</strong> <br />
            用例描述的是对参与者来说有价值的一系列行动，而不是特性集。例如，&#8220;招收研习班的学生&#8221;用例描述的是学生如何与系统交互来参加研习班。它没有描述用户界面看上去是什么样子，或者它是如何工作的。有一些其它的模型来描述这些重要的信息，例如用户界面模型和增补规范。面向对象分析非常复杂，因此需要对它使用几种模型，并且应该适当地应用每一种模型。 </p>
            <p><strong>用例只记载行为需求。</strong> <br />
            用例既不是类规范，也不是数据规范。这是应该由概念性模型捕捉的一种信息，在对象世界中，它是通过 UML类模型建模的。您往往会引用概念性模型中描述的类，例如，&#8220;参加研习班&#8221;用例包括了&#8220;研习班&#8221;和&#8220;学生&#8221;等概念，它们都将由概念性模型描述。 </p>
            <p><strong>不要忘记用户界面。</strong> <br />
            系统用例经常引用主用户界面 (UI)元素，这些元素常常称为&#8220;边界&#8221;或&#8220;用户界面&#8221;项，例如 HTML页面和报表。用例有时也引用一些次要的 UI元素，例如按钮或数据输入字段，但这种级别的细节并不太常见。 </p>
            <p><strong>创建用例模板。</strong> <br />
            用例包含了相当数量的信息，这些信息可以轻易地以常见格式记载。您应该考虑开发自己的模板（请参阅技巧&#8220; <a href="http://www.ibm.com/developerworks/library/ws-tip-docusecase.html?S_TACT=105AGX52&amp;S_CMP=cn-a-r">记载用例</a>&#8221;）。 </p>
            <p><strong>始终如一地组织用例图。</strong> <br />
            一般的做法是垂直地绘制继承 (inheritance) 和扩展 (extend)关联，在父／基本用例下面绘制继承／扩展用例。同样，通常水平绘制包含(include) 关联。请注意，这些是简单的经验法则 --只要始终遵循这些法则，产生的图将很容易理解。 </p>
            <p><strong>不要忘记系统对参与者行动的响应。</strong> <br />
            用例既应该描述参与者是如何与系统交互的，也应该描述系统如何响应这些交互。例如，在&#8220;参加研习班&#8221;用例中，如果系统在学生表明他们希望参加研习班时没有做出响应，学生就会很沮丧地离开。 </p>
            <p><strong>备选行动过程非常重要。</strong> <br />
            如果一切顺利，使用的将是基本行动过程 --但也不要忘记备选过程。引入备选过程是为了描述潜在的使用错误以及商业逻辑错误和异常。这些重要的信息对于驱动系统的设计来说很有必要，因此不要忘记在用例中对它们建模。 </p>
            <p><strong>不要被 &lt;&lt;include&gt;&gt; 和 &lt;&lt;extend&gt;&gt;关联所困扰。</strong> <br />
            我不是很确定到底发生了什么事，但我总是在想包含 (include) 和扩展(extend) 关联，以及旧版本 UML 中使用 (uses) 和扩展 (extends)关联的正确使用从来没有得到很好的描述。结果，用例建模小组往往在这些关联的正确应用上争论不休，在整个建模技术中一些有趣但次要的部分上浪费了惊人的时间。我曾在一个组织中工作，这家组织居然取缔了&lt;&lt;include&gt;&gt; 和 &lt;&lt;extend&gt;&gt;原型的使用，几个星期后，当意识到公司仍然需要这些概念时不得不撤消了这种极端的解决方案，而这时该组织对它们的正确使用还没有达成共识。 </p>
            <p><strong>让用例带动用户文档。</strong> <br />
            用户文档的目的是描述如何使用系统。每个用例都描述了参与者通过使用系统所采取的一系列动作。简而言之，用例包含从中开始编写问党用户稳当的信息。例如，可以使用&#8220;参加研习班&#8221;用例作为基础来编写系统用户文档的&#8220;如何参加研习班&#8221;一节。 </p>
            <p><strong>让用例带动演示。</strong> <br />
            软件开发过程中的一部分是向项目资金管理者通报工作成果，因此有时需要提供演示。因为用例是从用户的角度编写的，它们包含了演示中对资金管理者可能希望听到的事物的有价值的深刻见解。换句话说，用例通常包含制定演示稿所需的逻辑。 </p>
            <br />
            <br />
            <p><a name="resources"><span class="atitle">参考资料 </span></a></p>
            <ul>
                <li>您可以参阅本文在 developerWorks 全球站点上的 <a href="http://www.ibm.com/developerworks/library/ws-tip-uml2.html?S_TACT=105AGX52&amp;S_CMP=cn-a-r">英文原文</a>. <br />
                <br />
                </li>
                <li><a href="http://www.ambysoft.com/theObjectPrimer.html"><em>The Object Primer 2nd Edition</em> </a>，由 Scott W. Ambler 著。New York: Cambridge University Press, 2001。 <br />
                <br />
                </li>
                <li><a href="http://www.ambysoft.com/inceptionPhase.html"><em>The Unified Process Inception Phase</em> </a>，由 Scott W. Ambler 和 Larry L. Constantine 合著。Gilroy, CA: R&amp;D Books, 2000。 <br />
                <br />
                </li>
                <li><a href="http://www.amazon.com/exec/obidos/ASIN/0201924781/ambysoftinc"><em>Software For Use: A Practical Guide to the Models and Methods of Usage-Centered Design</em> </a>，由 Larry L. Constantine and Lucy A.D. Lockwood 合著。 <br />
                <br />
                </li>
                <li><a href="http://www.amazon.com/exec/obidos/ASIN/020130998X/ambysoftinc"><em>The Unified Modeling Language Reference Manual</em> </a>，由 James Rumbaugh、Grady Booch 和 Ivar Jacobson 合著。Reading, MA: Addison-Wesley Longman, Inc., 1999。 <br />
                </li>
            </ul>
            <br />
            <br />
            <p><a name="author"><span class="atitle">关于作者</span></a></p>
            <table cellspacing="0" cellpadding="0" width="100%" border="0">
                <tbody>
                    <tr>
                        <td colspan="3"><img height="5" alt="" src="http://www.ibm.com/i/c.gif" width="100%" /></td>
                    </tr>
                    <tr valign="top" align="left">
                        <td>
                        <p><img height="71" alt="Author photo" src="http://www.ibm.com/developerworks/cn/i/scottambler.jpg" width="64" align="left" /></p>
                        </td>
                        <td><img height="5" alt="" src="http://www.ibm.com/i/c.gif" width="4" /></td>
                        <td width="100%">
                        <p>Scott W. Ambler 是 <a href="http://www.ronin-intl.com/">Ronin International</a> 的总裁，该公司是一家专门提供面向对象软件过程指导、体系结构建模和 Enterprise JavaBean (EJB) 开发的咨询企业。他创作或者与其他人合著了几本有关面向对象开发的书籍，包括最近出版的 <em>Object Primer 2nd Edition</em>，该书详细介绍了本文所概述的主题。可以通过 <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#115;&#99;&#111;&#116;&#116;&#46;&#97;&#109;&#98;&#108;&#101;&#114;&#64;&#114;&#111;&#110;&#105;&#110;&#45;&#105;&#110;&#116;&#108;&#46;&#99;&#111;&#109;&#63;&#99;&#99;&#61;&#115;&#99;&#111;&#116;&#116;&#46;&#97;&#109;&#98;&#108;&#101;&#114;&#64;&#114;&#111;&#110;&#105;&#110;&#45;&#105;&#110;&#116;&#108;&#46;&#99;&#111;&#109;">scott.ambler@ronin-intl.com</a> 与他联系，他的网站位于 <a href="http://www.ambysoft.com/">www.ambysoft.com</a>。 </p>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            </td>
        </tr>
    </tbody>
</table><img src ="http://www.blogjava.net/hulizhong/aggbug/258866.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hulizhong/" target="_blank">二胡</a> 2009-03-10 17:36 <a href="http://www.blogjava.net/hulizhong/archive/2009/03/10/258866.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用例建模指南</title><link>http://www.blogjava.net/hulizhong/archive/2009/03/10/258766.html</link><dc:creator>二胡</dc:creator><author>二胡</author><pubDate>Tue, 10 Mar 2009 04:04:00 GMT</pubDate><guid>http://www.blogjava.net/hulizhong/archive/2009/03/10/258766.html</guid><wfw:comment>http://www.blogjava.net/hulizhong/comments/258766.html</wfw:comment><comments>http://www.blogjava.net/hulizhong/archive/2009/03/10/258766.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/hulizhong/comments/commentRss/258766.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hulizhong/services/trackbacks/258766.html</trackback:ping><description><![CDATA[转 http://www.ibm.com/developerworks/cn/rational/r-usecase-atm/<br />
<table id="content-table" cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr valign="top">
            <td width="100%">
            <table cellspacing="0" cellpadding="0" width="100%" border="0">
                <tbody>
                    <tr valign="top">
                        <td width="100%">
                        <h1>用例建模指南</h1>
                        <img class="display-img" height="6" alt="" src="http://www.ibm.com/i/c.gif" width="1" /></td>
                        <td class="no-print" width="192"><img height="18" alt="developerWorks" src="http://www.ibm.com/developerworks/i/dw.gif" width="192" /></td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr valign="top">
            <td width="10"><img height="1" alt="" src="http://www.ibm.com/i/c.gif" width="10" /></td>
            <td width="100%">
            <table class="no-print" cellspacing="0" cellpadding="0" width="160" align="right" border="0">
                <tbody>
                    <tr>
                        <td width="10"><img height="1" alt="" src="http://www.ibm.com/i/c.gif" width="10" /></td>
                        <td>
                        <table cellspacing="0" cellpadding="0" width="150" border="0">
                            <tbody>
                                <tr>
                                    <td class="v14-header-1-small">文档选项</td>
                                </tr>
                            </tbody>
                        </table>
                        <table class="v14-gray-table-border" cellspacing="0" cellpadding="0" border="0">
                            <tbody>
                                <tr>
                                    <td class="no-padding" width="150"><noscript></noscript><noscript></noscript>
                                    <table cellspacing="0" cellpadding="0" width="143" border="0">
                                        <script language="JavaScript" type="text/javascript">
<!-- document.write('<tr valign="top"><td width="8"><img src="//www.ibm.com/i/c.gif" width="8" height="1" alt="" /></td><td width="16"><img alt="将打印机的版面设置成横向打印模式" height="16" src="//www.ibm.com/i/v14/icons/printer.gif" width="16" vspace="3"  /></td><td width="122"><p><strong><a class="smallplainlink" href="javascript:print()">打印本页</a></strong></p></td></tr>');
//-->
</script>
                                        <tbody>
                                            <tr valign="top">
                                                <td width="8"><img height="1" alt="" src="http://www.ibm.com/i/c.gif" width="8" /></td>
                                                <td width="16"><img height="16" alt="将打印机的版面设置成横向打印模式" src="http://www.ibm.com/i/v14/icons/printer.gif" width="16" vspace="3" /></td>
                                                <td width="122">
                                                <p><strong><a class="smallplainlink" href="javascript:print()">打印本页</a></strong></p>
                                                </td>
                                            </tr>
                                            <form name="email" action="https://www.ibm.com/developerworks/secure/email-it.jsp">
                                            </form>
                                            <input type="hidden" value="用例(Use Case)是一种描述系统需求的方法，使用用例的方法来描述系统需求的过程就是用例建模。用例方法最早是由Iva Jackboson博士提出的，后来被综合到UML规范之中，成为一种标准化的需求表述体系。用例的使用在RUP中被推崇备至，整个RUP流程都被称作是'用例驱动'(Use-Case Driven)的，各种类型的开发活动包括项目管理、分析设计、测试、实现等都是以系统用例为主要输入工件，用例模型奠定了整个系统软件开发的基础。" name="body" /><input type="hidden" value="用例建模指南" name="subject" /><input type="hidden" value="cn" name="lang" /> <script language="JavaScript" type="text/javascript">
<!-- document.write('<tr valign="top"><td width="8"><img src="//www.ibm.com/i/c.gif" width="8" height="1" alt="" /></td><td width="16"><img src="//www.ibm.com/i/v14/icons/em.gif" height="16" width="16" vspace="3" alt="将此页作为电子邮件发送"  /></td><td width="122"><p><a class="smallplainlink" href="javascript:document.email.submit();"><strong>将此页作为电子邮件发送</strong></a></p></td></tr>');
//-->
</script>
                                            <tr valign="top">
                                                <td width="8"><img height="1" alt="" src="http://www.ibm.com/i/c.gif" width="8" /></td>
                                                <td width="16"><img height="16" alt="将此页作为电子邮件发送" src="http://www.ibm.com/i/v14/icons/em.gif" width="16" vspace="3" /></td>
                                                <td width="122">
                                                <p><a class="smallplainlink" href="javascript:document.email.submit();"><strong>将此页作为电子邮件发送</strong></a></p>
                                                </td>
                                            </tr>
                                        </tbody>
                                    </table>
                                    </td>
                                </tr>
                            </tbody>
                        </table>
                        <!--start RESERVED FOR FUTURE USE INCLUDE FILES--><!-- this content will be automatically generated across all content areas --><!--end RESERVED FOR FUTURE USE INCLUDE FILES--><br />
                        </td>
                    </tr>
                </tbody>
            </table>
            <p>级别： 初级</p>
            <p><a href="http://www.ibm.com/developerworks/cn/rational/r-usecase-atm/#author">傅纯一</a>, Rational中国区技术销售经理, IBM中国有限公司软件部<br />
            </p>
            <p>2004 年 11 月 01 日</p>
            <blockquote>用例(Use Case)是一种描述系统需求的方法，使用用例的方法来描述系统需求的过程就是用例建模。用例方法最早是由Iva Jackboson博士提出的，后来被综合到UML规范之中，成为一种标准化的需求表述体系。用例的使用在RUP中被推崇备至，整个RUP流程都被称作是"用例驱动"(Use-Case Driven)的，各种类型的开发活动包括项目管理、分析设计、测试、实现等都是以系统用例为主要输入工件，用例模型奠定了整个系统软件开发的基础。</blockquote><!--start RESERVED FOR FUTURE USE INCLUDE FILES--><!-- include java script once we verify teams wants to use this and it will work on dbcs and cyrillic characters --><!--end RESERVED FOR FUTURE USE INCLUDE FILES-->
            <p><a name="N10033"><span class="atitle">1. 什么是用例？</span></a></p>
            <p>在介始用例方法之前，我们首先来看一下传统的需求表述方式-"软件需求规约"(Software Requirement Specification)。传统的软件需求规约基本上采用的是功能分解的方式来描述系统功能，在这种表述方式中，系统功能被分解到各个系统功能模块中，我们通过描述细分的系统模块的功能来达到描述整个系统功能的目的。一个典型的软件需求规约可能具有以下形式：</p>
            <br />
            <img height="294" alt="" src="http://www.ibm.com/developerworks/cn/rational/r-usecase-atm/images/1.gif" width="315" border="0" /> <br />
            <p>采用这种方法来描述系统需求，非常容易混淆需求和设计的界限，这样的表述实际上已经包含了部分的设计在内。由此常常导致这样的迷惑：系统需求应该详细到何种程度？一个极端就是需求可以详细到概要设计，因为这样的需求表述既包含了外部需求也包含了内部设计。在有些公司的开发流程中，这种需求被称为"内部需求"，而对应于用户的原始要求则被称之为"外部需求"。</p>
            <p>功能分解方法的另一个缺点是这种方法分割了各项系统功能的应用环境，从各项功能项入手，你很难了解到这些功能项是如何相互关联来实现一个完成的系统服务的。所以在传统的SRS文档中，我们往往需要另外一些章节来描述系统的整体结构及各部分之间的相互关联，这些内容使得SRS需求更象是一个设计文档。</p>
            <p><a name="N10053"><span class="smalltitle">1.1 参与者和用例</span></a></p>
            <p>从用户的角度来看，他们并不想了解系统的内部结构和设计，他们所关心的是系统所能提供的服务，也就是被开发出来的系统将是如何被使用的，这就用例方法的基本思想。用例模型主要由以下模型元素构成：</p>
            <ul>
                <li>参与者(Actor) <br />
                参与者是指存在于被定义系统外部并与该系统发生交互的人或其他系统，他们代表的是系统的使用者或使用环境。 </li>
                <li>用例(Use Case) <br />
                用例用于表示系统所提供的服务，它定义了系统是如何被参与者所使用的，它描述的是参与者为了使用系统所提供的某一完整功能而与系统之间发生的一段对话。 </li>
                <li>通讯关联(Communication Association) <br />
                通讯关联用于表示参与者和用例之间的对应关系，它表示参与者使用了系统中的哪些服务（用例），或者说系统所提供的服务（用例）是被哪些参与者所使用的。 </li>
            </ul>
            <p>这大三种模型元素在UML中的表述如下图所示。</p>
            <br />
            <img height="89" alt="" src="http://www.ibm.com/developerworks/cn/rational/r-usecase-atm/images/image006.gif" width="341" border="0" /> <br />
            <p>以银行自动提款机(ATM)为例，它的主要功能可以由下面的用例图来表示。ATM的主要使用者是银行客户，客户主要使用自动提款机来进行银行帐户的查询、提款和转帐交易。</p>
            <br />
            <img height="230" alt="" src="http://www.ibm.com/developerworks/cn/rational/r-usecase-atm/images/image008.gif" width="261" border="0" /> <br />
            <p>通讯关联表示的是参与者和用例之间的关系，箭头表示在这一关系中哪一方是对话的主动发起者，箭头所指方是对话的被动接受者；如果你不想强调对话中的主动与被动关系，可以使用不带箭头的关联实线。在参与者和用例之间的信息流不是由通讯关联来表示的，该信息流是缺省存在的（用例本身描述的就是参与者和系统之间的对话），并且信息流向是双向的，它与通讯关联箭头所指的方向亳无关系。</p>
            <p><a name="N10099"><span class="smalltitle">1.2 用例的内容</span></a></p>
            <p>用例图使我们对系统的功能有了一个整体的认知，我们可以知道有哪些参与者会与系统发生交互，每一个参与者需要系统为它提供什么样的服务。用例描述的是参与者与系统之间的对话，但是这个对话的细节并没有在用例图中表述出来，针对每一个用例我们可以用事件流来描述这一对话的细节内容。如在ATM系统中的"提款" 用例可以用事件流表述如下：</p>
            <p>提款-基本事件流</p>
            <p>1. 用户插入信用卡</p>
            <p>2. 输入密码</p>
            <p>3. 输入提款金额</p>
            <p>4. 提取现金</p>
            <p>5. 退出系统，取回信用卡</p>
            <p>但是这只描述了提款用例中最顺利的一种情况，作为一个实用的系统，我们还必须考虑可能发生的各种其他情况，如信用卡无效、输入密码错、用户帐号中的现金余额不够等，所有这些可能发生的各种情况（包括正常的和异常的）被称之为用例的场景(Scenario)，场景也被称作是用例的实例(Instance)。在用例的各种场景中，最常见的场景是用基本流(Basic Flow)来描述的，其他的场景则是用备选流(Alternative Flow)来描述。对于ATM系统中的"提款"用例，我们可以得到如下一些备选流：</p>
            <p>提款-备选事件流</p>
            <p>备选流一：用户可以在基本流中的任何一步选择退出，转至基本流步骤5。</p>
            <p>备选流二：在基本流步骤1中，用户插入无效信用卡，系统显示错误并退出信用卡，用例结束。</p>
            <p>备选流三：在基本流步骤２中，用户输入错误密码，系统显示错误并提示用户重新输入密码，重新回到基本流步骤2；三次输入密码错误后，信用卡被系统没收，用例结束。</p>
            <p>&#8230;</p>
            <p>通过基本流与备选流的组合，就可以将用例所有可能发生的各种场景全部描述清楚。我们在描述用例的事件流的时候，就是要尽可能地将所有可能的场景都描述出来，以保证需求的完备性。</p>
            <p><a name="N100C9"><span class="smalltitle">1.3 用例方法的优点</span></a></p>
            <p>用例方法完全是站在用户的角度上（从系统的外部）来描述系统的功能的。在用例方法中，我们把被定义系统看作是一个黑箱，我们并不关心系统内部是如何完成它所提供的功能的。用例方法首先描述了被定义系统有哪些外部使用者（抽象成为Actor），这些使用者与被定义系统发生交互；针对每一参与者，用例方法又描述了系统为这些参与者提供了什么样的服务（抽象成为Use Case），或者说系统是如何被这些参与者使用的。所以从用例图中，我们可以得到对于被定义系统的一个总体印象。</p>
            <p>与传统的功能分解方式相比，用例方法完全是从外部来定义系统的功能，它把需求与设计完全分离开来。在面向对象的分析设计方法中，用例模型主要用于表述系统的功能性需求，系统的设计主要由对象模型来记录表述。另外，用例定义了系统功能的使用环境与上下文，每一个用例描述的是一个完整的系统服务。用例方法比传统的 SRS更易于被用户所理解，它可以作为开发人员和用户之间针对系统需求进行沟通的一个有效手段。</p>
            <p>在RUP中，用例被作为整个软件开发流程的基础，很多类型的开发活动都把用例作为一个主要的输入工件(Artifact)，如项目管理、分析设计、测试等。根据用例来对目标系统进行测试，可以根据用例中所描述的环境和上下文来完整地测试一个系统服务，可以根据用例的各个场景(Scenario)来设计测试用例，完全地测试用例的各种场景可以保证测试的完备性。</p>
            <br />
            <table cellspacing="0" cellpadding="0" width="100%" border="0">
                <tbody>
                    <tr>
                        <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br />
                        <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td>
                    </tr>
                </tbody>
            </table>
            <table class="no-print" cellspacing="0" cellpadding="0" align="right">
                <tbody>
                    <tr align="right">
                        <td><img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" /><br />
                        <table cellspacing="0" cellpadding="0" border="0">
                            <tbody>
                                <tr>
                                    <td valign="middle"><img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" /><br />
                                    </td>
                                    <td valign="top" align="right"><a class="fbox" href="http://www.ibm.com/developerworks/cn/rational/r-usecase-atm/#main"><strong>回页首</strong></a></td>
                                </tr>
                            </tbody>
                        </table>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <br />
            <p><a name="N100D8"><span class="atitle">2. 建立用例模型</span></a></p>
            <p>使用用例的方法来描述系统的功能需求的过程就是用例建模，用例模型主要包括以下两部分内容：</p>
            <ul>
                <li>用例图(Use Case Diagram) <br />
                确定系统中所包含的参与者、用例和两者之间的对应关系，用例图描述的是关于系统功能的一个概述。 </li>
                <li>用例规约(Use Case Specification) <br />
                针对每一个用例都应该有一个用例规约文档与之相对应，该文档描述用例的细节内容。 </li>
            </ul>
            <p>在用例建模的过程中，我们建议的步聚是先找出参与者，再根据参与者确定每个参与者相关的用例，最后再细化每一个用例的用例规约。</p>
            <p><a name="N100F1"><span class="smalltitle">2.1 寻找参与者</span></a></p>
            <p>所谓的参与者是指所有存在于系统外部并与系统进行交互的人或其他系统。通俗地讲，参与者就是我们所要定义系统的使用者。寻找参与者可以从以下问题入手：</p>
            <ul>
                <li>系统开发完成之后，有哪些人会使用这个系统？</li>
                <li>系统需要从哪些人或其他系统中获得数据？</li>
                <li>系统会为哪些人或其他系统提供数据？</li>
                <li>系统会与哪些其他系统相关联？</li>
                <li>系统是由谁来维护和管理的？</li>
            </ul>
            <p>这些问题有助于我们抽象出系统的参与者。对于ATM机的例子，回答这些问题可以使我们找到更多的参与者：操作员负责维护和管理ATM机系统、ATM机也需要与后台服务器进行通讯以获得有关用户帐号的相关信息。</p>
            <br />
            <img height="178" alt="" src="http://www.ibm.com/developerworks/cn/rational/r-usecase-atm/images/image010.gif" width="456" border="0" /> <br />
            <p><strong>2.1.1 系统边界决定了参与者</strong> </p>
            <p>参与者是由系统的边界所决定的，如果我们所要定义的系统边界仅限于ATM机本身，那么后台服务器就是一个外部的系统，可以抽象为一个参与者。</p>
            <br />
            <img height="91" alt="" src="http://www.ibm.com/developerworks/cn/rational/r-usecase-atm/images/image012.gif" width="341" border="0" /> <br />
            <p>如果我们所要定义的系统边界扩大至整个银行系统，ATM机和后台服务器都是整个银行系统的一部分，这时候后台服务器就不再被抽象成为一个参与者。</p>
            <br />
            <img height="104" alt="" src="http://www.ibm.com/developerworks/cn/rational/r-usecase-atm/images/image014.gif" width="370" border="0" /> <br />
            <p>值得注意的是，用例建模时不要将一些系统的组成结构作为参与者来进行抽象，如在ATM机系统中，打印机只是系统的一个组成部分，不应将它抽象成一个独立的参与者；在一个MIS管理系统中，数据库系统往往只作为系统的一个组成部分，一般不将其单独抽象成一个参与者。</p>
            <p><strong>2.1.2 特殊的参与者――系统时钟</strong> </p>
            <p>有时候我们需要在系统内部定时地执行一些操作，如检测系统资源使用情况、定期地生成统计报表等等。从表面上看，这些操作并不是由外部的人或系统触发的，应该怎样用用例方法来表述这一类功能需求呢？对于这种情况，我们可以抽象出一个系统时钟或定时器参与者，利用该参与者来触发这一类定时操作。从逻辑上，这一参与者应该被理解成是系统外部的，由它来触发系统所提供的用例对话。</p>
            <br />
            <img height="88" alt="" src="http://www.ibm.com/developerworks/cn/rational/r-usecase-atm/images/image016.gif" width="262" border="0" /> <br />
            <p><a name="N1016B"><span class="smalltitle">2.2 确定用例</span></a></p>
            <p>找到参与者之后，我们就可以根据参与者来确定系统的用例，主要是看各参与者需要系统提供什么样的服务，或者说参与者是如何使用系统的。寻找用例可以从以下问题入手（针对每一个参与者）：</p>
            <ul>
                <li>参与者为什么要使用该系统？</li>
                <li>参与者是否会在系统中创建、修改、删除、访问、存储数据？如果是的话，参与者又是如何来完成这些操作的？</li>
                <li>参与者是否会将外部的某些事件通知给该系统？</li>
                <li>系统是否会将内部的某些事件通知该参与者？</li>
            </ul>
            <p>综合以上所述，ATM系统的用例图可表示如下，</p>
            <br />
            <img height="279" alt="" src="http://www.ibm.com/developerworks/cn/rational/r-usecase-atm/images/image018.gif" width="403" border="0" /> <br />
            <p>在用例的抽取过程中，必须注意：用例必须是由某一个主角触发而产生的活动，即每个用例至少应该涉及一个主角。如果存在与主角不进行交互的用例，就可以考虑将其并入其他用例；或者是检查该用例相对应的参与者是否被遗漏，如果是，则补上该参与者。反之，每个参与者也必须至少涉及到一个用例，如果发现有不与任何用例相关联的参与者存在，就应该考虑该参与者是如何与系统发生对话的，或者由参与者确定一个新的用例，或者该参与者是一个多余的模型元素，应该将其删除。</p>
            <p>可视化建模的主要目的之一就是要增强团队的沟通，用例模型必须是易于理解的。用例建模往往是一个团队开发的过程，系统分析员在建模过程中必须注意参与者和用例的名称应该符合一定的命名约定，这样整个用例模型才能够符合一定的风格。如参与者的名称一般都是名词，用例名称一般都是动宾词组等。</p>
            <p>对于同一个系统，不同的人对于参与者和用例都可能有不同的抽象结果，因而得到不同的用例模型。我们需要在多个用例模型方案中选择一种"最佳"（或"较佳"）的结果，一个好的用例模型应该能够容易被不同的涉众所理解，并且不同的涉众对于同一用例模型的理解应该是一致的。</p>
            <p><a name="N101A0"><span class="smalltitle">2.3 描述用例规约</span></a></p>
            <p>应该避免这样一种误解――认为由参与者和用例构成的用例图就是用例模型，用例图只是在总体上大致描述了系统所能提供的各种服务，让我们对于系统的功能有一个总体的认识。除此之外，我们还需要描述每一个有例的详细信息，这些信息包含在用例规约中，用例模型是由用例图和每一个用例的详细描述――用例规约所组成的。RUP中提供了用例规约的模板，每一个用例的用例规约都应该包含以下内容：</p>
            <ul>
                <li>简要说明 (Brief Description) <br />
                简要介绍该用例的作用和目的。 </li>
                <li>事件流 (Flow of Event) <br />
                包括基本流和备选流，事件流应该表示出所有的场景。 </li>
                <li>用例场景 (Use-Case Scenario) <br />
                包括成功场景和失败场景，场景主要是由基本流和备选流组合而成的。 </li>
                <li>特殊需求 (Special Requirement) <br />
                描述与该用例相关的非功能性需求（包括性能、可靠性、可用性和可扩展性等）和设计约束（所使用的操作系统、开发工具等）。 </li>
                <li>前置条件 (Pre-Condition) <br />
                执行用例之前系统必须所处的状态。 </li>
                <li>后置条件 (Post-Condition) <br />
                用例执行完毕后系统可能处于的一组状态。 </li>
            </ul>
            <p>用例规约基本上是用文本方式来表述的，为了更加清晰地描述事件流，也可以选择使用状态图、活动图或序列图来辅助说明。只要有助于表达的简洁明了，就可以在用例中任意粘贴用户界面和流程的图形化显示方式，或是其他图形。如活动图有助于描述复杂的决策流程，状态转移图有助于描述与状态相关的系统行为，序列图适合于描述基于时间顺序的消息传递。</p>
            <p><strong>2.3.1 基本流</strong> </p>
            <p>基本流描述的是该用例最正常的一种场景，在基本流中系统执行一系列活动步骤来响应参与者提出的服务请求。我们建议用以下格式来描述基本流：</p>
            <p>1) 每一个步骤都需要用数字编号以清楚地标明步骤的先后顺序。</p>
            <p>2) 用一句简短的标题来概括每一步骤的主要内容，这样阅读者可以通过浏览标题来快速地了解用例的主要步骤。在用例建模的早期，我们也只需要描述到事件流步骤标题这一层，以免过早地陷入到用例描述的细节中去。</p>
            <p>3) 当整个用例模型基本稳定之后，我们再针对每一步骤详细描述参与者和系统之间所发生的交互。建议采用双向(roundtrip)描述法来保证描述的完整性，即每一步骤都需要从正反两个方面来描述:(1)参与者向系统提交了什么信息；(2)对此系统有什么样的响应。具体例子请参见附录。</p>
            <p>在描述参与者和系统之间的信息交换时，需指出来回传递的具体信息。例如，只表述参与者输入了客户信息就不够明确，最好明确地说参与者输入了客户姓名和地址。通常可以利用词汇表让用例的复杂性保持在可控范围内，可以在词汇表中定义客户信息等内容，使用例不至于陷入过多的细节。</p>
            <p><strong>2.3.2 备选流</strong> </p>
            <p>备选流负责描述用例执行过程中异常的或偶尔发生的一些情况，备选流和基本流的组合应该能够覆盖该用例所有可能发生的场景。在描述备选流时，应该包括以下几个要素：</p>
            <p>1) 起点：该备选流从事件流的哪一步开始；</p>
            <p>2) 条件：在什么条件下会触发该备选流；</p>
            <p>3) 动作：系统在该备选流下会采取哪些动作；</p>
            <p>4) 恢复：该备选流结束之后，该用例应如何继续执行。</p>
            <p>备选流的描述格式可以与基本流的格式一致，也需要编号并以标题概述其内容，编号前可以加以字母前缀A(Alternative)以示与基本流步骤相区别。</p>
            <p><strong>2.3.3 用例场景</strong> </p>
            <p>用例在实际执行的时候会有很多的不同情况发生，称之为用例场景；也可以说场景是用例的实例，我们在描述用例的时候要覆盖所有的用例场景，否则就有可能导致需求的遗漏。在用例规约中，场景的描述可以由基本流和备选流的组合来表示。场景既可以帮助我们防止需求的遗漏，同时也可以对后续的开发工作起到很大的帮助：开发人员必须实现所有的场景、测试人员可以根据用例场景来设计测试用例。</p>
            <p><strong>2.3.4 特殊需求</strong> </p>
            <p>特殊需求通常是非功能性需求，它为一个用例所专有，但不适合在用例的事件流文本中进行说明。特殊需求的例子包括法律或法规方面的需求、应用程序标准和所构建系统的质量属性（包括可用性、可靠性、性能或支持性需求等）。此外，其他一些设计约束，如操作系统及环境、兼容性需求等，也可以在此节中记录。</p>
            <p>需要注意的是，这里记录的是专属于该用例的特殊需求；对于一些全局的非功能性需求和设计约束，它们并不是该用例所专有的，应把它们记录在《补充规约》中。</p>
            <p><strong>2.3.5 前置和后置条件</strong> </p>
            <p>前置条件是执行用例之前必须存在的系统状态，后置条件是用例一执行完毕后系统可能处于的一组状态。</p>
            <p><a name="N10218"><span class="smalltitle">2.4 检查用例模型</span></a></p>
            <p>用例模型完成之后，可以对用例模型进行检查，看看是否有遗漏或错误之处。主要可以从以下几个方面来进行检查：</p>
            <ul>
                <li>功能需求的完备性 <br />
                现有的用例模型是否完整地描述了系统功能，这也是我们判断用例建模工作是否结束的标志。如果发现还有系统功能没有被记录在现有的用例模型中，那么我们就需要抽象一些新的用例来记录这些需求，或是将他们归纳在一些现有的用例之中。 </li>
                <li>模型是否易于理解 <br />
                用例模型最大的优点就在于它应该易于被不同的涉众所理解，因而用例建模最主要的指导原则就是它的可理解性。用例的粒度、个数以及模型元素之间的关系复杂程度都应该由该指导原则决定。 </li>
                <li>是否存在不一致性 <br />
                系统的用例模型是由多个系统分析员协同完成的，模型本身也是由多个工件所组成的，所以我们要特别注意不同工件之前是否存在前后矛盾或冲突的地方，避免在模型内部产生不一致性。不一致性会直接影响到需求定义的准确性。 </li>
                <li>避免二义性语义 <br />
                好的需求定义应该是无二义性的，即不同的人对于同一需求的理解应该是一致的。在用例规约的描述中，应该避免定义含义模糊的需求，即无二义性。 </li>
            </ul>
            <br />
            <table cellspacing="0" cellpadding="0" width="100%" border="0">
                <tbody>
                    <tr>
                        <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br />
                        <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td>
                    </tr>
                </tbody>
            </table>
            <table class="no-print" cellspacing="0" cellpadding="0" align="right">
                <tbody>
                    <tr align="right">
                        <td><img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" /><br />
                        <table cellspacing="0" cellpadding="0" border="0">
                            <tbody>
                                <tr>
                                    <td valign="middle"><img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" /><br />
                                    </td>
                                    <td valign="top" align="right"><a class="fbox" href="http://www.ibm.com/developerworks/cn/rational/r-usecase-atm/#main"><strong>回页首</strong></a></td>
                                </tr>
                            </tbody>
                        </table>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <br />
            <p><a name="N10238"><span class="atitle">3. 系统需求</span></a></p>
            <p>RUP中根据FURPS+模型将系统需求分为以下几类：</p>
            <ul>
                <li>功能(Functionality)</li>
                <li>可用性(Usability)</li>
                <li>可靠性(Reliability)</li>
                <li>性能(Performance)</li>
                <li>可支持性(Supportability)</li>
                <li>设计约束等</li>
            </ul>
            <p>除了第一项功能性需求之外的其他需求都归之为非功能性需求。</p>
            <p><a name="N10259"><span class="smalltitle">3.1 需求工件集</span></a></p>
            <p>用例模型主要用于描述系统的功能性需求，对于其他的非功能性需要用其他文档来记录。RUP中定义了如下的需求工件集合。</p>
            <ul>
                <li>用例模型：记录功能性需求
                <ul>
                    <li>用例图：描述参与者和用例之间的关系</li>
                    <li>用例规约：描述每一个用例的细节信息</li>
                </ul>
                </li>
                <li>补充规约：记录一些全局性的功能需求、非功能性需求和设计约束等</li>
                <li>词汇表：记录一些系统需求相关的术语</li>
            </ul>
            <p>在实际应用中，除了这些工件之外，我们还可以根据实际需求灵活选用其他形式的文档来补充说明需求。并不是所有的系统需求都适保合用用例模型来描述的，如编译器，我们很难用用例方法来表述它所处理的语言的方法规则，在这种情况下，采用传统的BNF范式来表述更加合适一些。在电信软件行业中，很多电信标准都是采用SDL语言来描述的，我们也不必用UML来改写这些标准（UML对SDL存在着这样的兼容性），只需将SDL形式的电信标准作为需求工件之一，在其他工件中对其加以引用就可以了。总之，万万不可拘泥于用例建模的形式，应灵活运用各种方式的长处。</p>
            <p><a name="N1027A"><span class="smalltitle">3.2 补充规约</span></a></p>
            <p>补充规约记录那些在用例模型中不易表述的系统需求，主要包括以下内容。</p>
            <ul>
                <li>功能性 <br />
                功能性需求主要在用例模型中刻画，但是也有部分需求不适合在用例中表述。有些功能性需求是全局性的，适用于所有的用例，如出错处理、I18N支持等，我们不需要在所有的用例中描述这些功能性需求，只需要在补充规约中统一描述就可以了。 </li>
                <li>可用性 <br />
                记录所有可用性相关的需求，如系统的使用者所需要的培训时间、是否应附合一些常见的可用性标准如Windows界面风格等。 </li>
                <li>可靠性 <br />
                定义系统可靠性相关的各种指标，包括： <br />
                <ul>
                    <li>可用性：指出可用时间百分比(xx.xx%)，系统处于使用、维护、降级模式等操作的小时数；</li>
                    <li>平均故障间隔时间(MTBF)：通常表示为小时数，但也可表示为天数、月数或年数；</li>
                    <li>平均修复时间(MTTR)：系统在发生故障后可以暂停运行的时间；</li>
                    <li>精确度：指出系统输出要求具备的精密度（分辨率）和精确度（按照某一已知的标准）；</li>
                    <li>最高错误或缺陷率：通常表示为bugs/KLOC（每千行代码的错误数目）或bugs/function-point（每个功能点的错误数目）。</li>
                </ul>
                </li>
                <li>性能 <br />
                记录系统性能相关的各种指标，包括： <br />
                <ul>
                    <li>对事务的响应时间（平均、最长）；</li>
                    <li>吞吐量（例如每秒处理的事务数）；</li>
                    <li>容量（例如系统可以容纳的客户或事务数）；</li>
                    <li>降级模式（当系统以某种形式降级时可接受的运行模式）；</li>
                    <li>资源利用情况：内存、磁盘、通信等。</li>
                </ul>
                </li>
                <li>可支持性 <br />
                定义所有与系统的可支持性或可维护性相关的需求，其中包括编码标准、命名约定、类库、如何来对系统进行维护操作和相应的维护实用工具等。 </li>
                <li>设计约束 <br />
                设计约束代表已经批准并必须遵循的设计决定，其中包括软件开发流程、开发工具、系统构架、编程语言、第三方构件类库、运行平台和数据库系统等等。 </li>
            </ul>
            <p><a name="N102CC"><span class="smalltitle">3.3 词汇表</span></a></p>
            <p>词汇表主要用于定义项目特定的术语，它有助于开发人员对项目中所用的术语有统一的理解和使用，它也是后续阶段中进行对象抽象的基础。</p>
            <br />
            <table cellspacing="0" cellpadding="0" width="100%" border="0">
                <tbody>
                    <tr>
                        <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br />
                        <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td>
                    </tr>
                </tbody>
            </table>
            <table class="no-print" cellspacing="0" cellpadding="0" align="right">
                <tbody>
                    <tr align="right">
                        <td><img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" /><br />
                        <table cellspacing="0" cellpadding="0" border="0">
                            <tbody>
                                <tr>
                                    <td valign="middle"><img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" /><br />
                                    </td>
                                    <td valign="top" align="right"><a class="fbox" href="http://www.ibm.com/developerworks/cn/rational/r-usecase-atm/#main"><strong>回页首</strong></a></td>
                                </tr>
                            </tbody>
                        </table>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <br />
            <p><a name="N102D5"><span class="atitle">4. 调整用例模型</span></a></p>
            <p>在一般的用例图中，我们只表述参与者和用例之间的关系，即它们之间的通讯关联。除此之外，我们还可以描述参与者与参与者之间的泛化 (generalization)、用例和用例之间的包含(include)、扩展(extend)和泛化(generalization)关系。我们利用这些关系来调整已有的用例模型，把一些公共的信息抽取出来重用，使得用例模型更易于维护。但是在应用中要小心选用这些关系，一般来说这些关系都会增加用例和关系的个数，从而增加用例模型的复杂度。而且一般都是在用例模型完成之后才对用例模型进行调整，所以在用例建模的初期不必要急于抽象用例之间的关系。</p>
            <p><a name="N102DE"><span class="smalltitle">4.1 参与者之间的关系</span></a></p>
            <p>参与者之间可以有泛化(Generalization)关系（或称为"继承"关系）。例如在需求分析中常见的权限控制问题（如下图所示），一般的用户只可以使用一些常规的操作，而管理员除了常规操作之外还需要进行一些系统管理工作，操作员既可以进行常规操作又可以进行一些配置操作。</p>
            <br />
            <img height="271" alt="" src="http://www.ibm.com/developerworks/cn/rational/r-usecase-atm/images/image020.gif" width="289" border="0" /> <br />
            <p>在这个例子中我们会发现管理员和操作员都是一种特殊的用户，他们拥有普通用户所拥有的全部权限，此外他们还有自己独有的权限。这里我们可进一步把普通用户和管理员、操作员之间的关系抽象成泛化(Generalization)关系，管理员和操作员可以继承普通用户的全部特性（包括权限），他们又可以有自己独有的特性（如操作、权限等）。这样可以显著减速少用例图中通讯关联的个数，简化用例模型，使之更易于理解。</p>
            <br />
            <img height="270" alt="" src="http://www.ibm.com/developerworks/cn/rational/r-usecase-atm/images/image022.gif" width="325" border="0" /> <br />
            <p><a name="N1030C"><span class="smalltitle">4.2 用例之间的关系</span></a></p>
            <p>用例描述的是系统外部可见的行为，是系统为某一个或几个参与者提供的一段完整的服务。从原则上来讲，用例之间都是并列的，它们之间并不存在着包含从属关系。但是从保证用例模型的可维护性和一致性角度来看，我们可以在用例之间抽象出包含(include)、扩展(extend)和泛化 (generalization)这几种关系。这几种关系都是从现有的用例中抽取出公共的那部分信息，然后通后过不同的方法来重用这部公共信息，以减少模型维护的工作量。</p>
            <p><strong>4.2.1 包含(include)</strong> </p>
            <p>包含关系是通过在关联关系上应用&lt;&lt;include&gt;&gt;构造型来表示的，如下图所示。它所表示的语义是指基础用例(Base)会用到被包含用例(Inclusion)，具体地讲，就是将被包含用例的事件流插入到基础用例的事件流中。</p>
            <br />
            <img height="80" alt="" src="http://www.ibm.com/developerworks/cn/rational/r-usecase-atm/images/image024.gif" width="393" border="0" /> <br />
            <p>包含关系是UML1.3中的表述，在UML1.1中，同等语义的关系被表述为使用(uses)，如下图。</p>
            <br />
            <img height="67" alt="" src="http://www.ibm.com/developerworks/cn/rational/r-usecase-atm/images/image026.gif" width="333" border="0" /> <br />
            <p>在 ATM机中，如果查询、取现、转帐这三个用例都需要打印一个回执给客户，我们就可以把打印回执这一部分内容提取出来，抽象成为一个单独的用例"打印回执"，而原有的查询、取现、转帐三个例都会包含这个用例。每当以后要对打印回执部分的需求进行修改时，就只需要改动一个用例，而不用在每一个用例都作相应修改，这样就提高了用例模型的可维护性。</p>
            <br />
            <img height="229" alt="" src="http://www.ibm.com/developerworks/cn/rational/r-usecase-atm/images/image028.gif" width="417" border="0" /> <br />
            <p>在基础用例的事件流中，我们只需要引用被包含用例即可。</p>
            <p>查询-基本事件流</p>
            <p>1. 用户插入信用卡</p>
            <p>2. 输入密码</p>
            <p>3. 选择查询</p>
            <p>4. 查看帐号余额</p>
            <p>5. 包含用例"打印回执"</p>
            <p>6. 退出系统，取回信用卡</p>
            <p>在这个例子中，多个用例需要用到同一段行为，我们可以把这段共同的行为单独抽象成为一个用例，然后让其他的用例来包含这一用例。从而避免在多个用例中重复性地描述同一段行为，也可以防止该段行为在多个用例中的描述出现不一致性。当需要修改这段公共的需求时，我们也只需要修改一个用例，避免同时修改多个用例而产生的不一致性和重复性工作。</p>
            <p>有时当某一个用例的事件流过于复杂时，为了简化用例的描述，我们也可以把某一段事件流抽象成为一个被包含的用例。这种情况类似于在过程设计语言中，将程序的某一段算法封装成一个子过程，然后再从主程序中调用这一子过程。</p>
            <p><strong>4.2.2 扩展(extend)</strong> </p>
            <p>扩展（extend）关系如下图所示，基础用例(Base)中定义有一至多个已命名的扩展点，扩展关系是指将扩展用例(Extension)的事件流在一定的条件下按照相应的扩展点插入到基础用例(Base)中。对于包含关系而言，子用例中的事件流是一定插入到基础用例中去的，并且插入点只有一个。而扩展关系可以根据一定的条件来决定是否将扩展用例的事件流插入基础用例事件流，并且插入点可以有多个。</p>
            <br />
            <img height="66" alt="" src="http://www.ibm.com/developerworks/cn/rational/r-usecase-atm/images/image030.gif" width="327" border="0" /> <br />
            <p>例如对于电话业务，可以在基本通话(Call)业务上扩展出一些增值业务如：呼叫等待(Call Waiting)和呼叫转移(Call Transfer)。我们可以用扩展关系将这些业务的用例模型描述如下。</p>
            <br />
            <img height="159" alt="" src="http://www.ibm.com/developerworks/cn/rational/r-usecase-atm/images/image032.gif" width="356" border="0" /> <br />
            <br />
            <img height="250" alt="" src="http://www.ibm.com/developerworks/cn/rational/r-usecase-atm/images/2.jpg" width="637" border="0" /> <br />
            <p>在这个例子中，呼叫等待和呼叫转移都是对基本通话用例的扩展，但是这两个用例只有在一定的条件下（如应答方正忙或应答方无应答）才会将被扩展用例的事件流嵌入基本通话用例的扩展点，并重用基本通话用例中的事件流。</p>
            <p>值得注意的是扩展用例的事件流往往可以也可抽象为基础用例的备选流，如上例中的呼叫等待和呼叫转移都可以作为基本通话用例的备选流而存在。但是基本通话用例已经是一个很复杂的用例了，选用扩展关系将增值业务抽象成为单独的用例可以避免基础用例过于复杂，并且把一些可选的操作独立封装在另外的用例中。</p>
            <p><strong>4.2.3 泛化(generalization)</strong> </p>
            <p>当多个用例共同拥有一种类似的结构和行为的时候，我们可以将它们的共性抽象成为父用例，其他的用例作为泛化关系中的子用例。在用例的泛化关系中，子用例是父用例的一种特殊形式，子用例继承了父用例所有的结构、行为和关系。在实际应用中很少使用泛化关系，子用例中的特殊行为都可以作为父用例中的备选流存在。</p>
            <br />
            <img height="148" alt="" src="http://www.ibm.com/developerworks/cn/rational/r-usecase-atm/images/image034.gif" width="299" border="0" /> <br />
            <p>以下是一个用例泛化关系的例子，执行交易是一种交易抽象，执行房产交易和执行证券交易都是一种特殊的交易形式。</p>
            <p>用例泛化关系中的事件流示例如下：</p>
            <br />
            <img height="312" alt="" src="http://www.ibm.com/developerworks/cn/rational/r-usecase-atm/images/3.gif" width="637" border="0" /> <br />
            <p><a name="N103EB"><span class="smalltitle">4.3 调整用例模型</span></a></p>
            <p>用例模型建成之后，我们可以对用例模型进行检视，看是否可以进一步简化用例模型、提高重用程度、增加模型的可维护性。主要可以从以下检查点(checkpoints)入手:</p>
            <ul>
                <li>用例之间是否相互独立？如果两个用例总是以同样的顺序被激活，可能需要将它们合并为一个用例。</li>
                <li>多个用例之间是否有非常相似的行为或事件流？如果有，可以考虑将它们合并为一个用例。</li>
                <li>用例事件流的一部分是否已被构建为另一个用例？如果是，可以让该用例包含(include)另一用例。</li>
                <li>是否应该将一个用例的事件流插入另一个用例的事件流中？如果是，利用与另一个用例的扩展关系(extend)来建立此模型。 </li>
            </ul>
            <br />
            <table cellspacing="0" cellpadding="0" width="100%" border="0">
                <tbody>
                    <tr>
                        <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br />
                        <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td>
                    </tr>
                </tbody>
            </table>
            <table class="no-print" cellspacing="0" cellpadding="0" align="right">
                <tbody>
                    <tr align="right">
                        <td><img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" /><br />
                        <table cellspacing="0" cellpadding="0" border="0">
                            <tbody>
                                <tr>
                                    <td valign="middle"><img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" /><br />
                                    </td>
                                    <td valign="top" align="right"><a class="fbox" href="http://www.ibm.com/developerworks/cn/rational/r-usecase-atm/#main"><strong>回页首</strong></a></td>
                                </tr>
                            </tbody>
                        </table>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <br />
            <p><a name="N10403"><span class="atitle">5. 管理用例模型复杂度</span></a></p>
            <p>一般小型的系统，其用例模型中包含的参与者和用例不会太多，一个用例图就可以容纳所有的参与者，所有的参与者和用例也可以并存于同一个层次结构中。对于较复杂的大中型系统，用例模型中的参与者和用例会大大增加，我们需要一些方法来有效地管理由于规模上升而造成的复杂度。</p>
            <p><a name="N1040C"><span class="smalltitle">5.1 用例包</span></a></p>
            <p>包 (Package)是UML中最常用的管理模型复杂度的机制，包也是UML中语义最简单的一种模型元素，它就是一种容器，在包中可以容纳其他任意的模型元素（包括其他的包）。在用例模型中，我们可以用构造型(Sterotype)&lt;&lt;use case&gt;&gt;来扩展标准UML包的语义，这种新的包叫作用例包(Use Case Package)，用于分类管理用例模型中的模型元素。</p>
            <p>我们可以根据参与者和用例的特性来对它们进行分类，分别置于不同的用例包管理之下。例如对于一个大型的企业管理信息系统，我们可以根据参与者和用例的内容将它们分别归于人力资源、财务、采购、销售、客务服务这些用例包之下。这样我们将整个用例模型划分成为两个层次，在第一层次我们看到的是系统功能总共分为五部分，在第二层次我们可以分别看到每一用例包内部的参与者和用例。</p>
            <br />
            <img height="192" alt="" src="http://www.ibm.com/developerworks/cn/rational/r-usecase-atm/images/image038.gif" width="272" border="0" /> <br />
            <p>一个用例模型需要有多少个用例包取决你想怎么样来管理用例模型的复杂度（包括参与者和用例的个数，以及它们之间的相互关系）。UML中的包其实就类似于文件系统中的目录，文件数量少的时候不需要额外的目录，文件数量一多就需要有多个目录来分类管理，同样一组文件不同的人会创建不同的目录结构来进行管理，关键是要保证在目录结构下每一个文件都要易于访问。同样的道理存在于用例建模之中，如何创建用例包以及用例包的个数取决于不同的系统和系统分析员，但要保证整个用例模型易于理解。</p>
            <p><a name="N1042C"><span class="smalltitle">5.2 用例的粒度</span></a></p>
            <p>我的系统需要有多少个用例？这是很多人在用例建模时会产生的疑惑。描述同一个系统，不同的人会产生不同的用例模型。例如对于各种系统中常见的"维护用户"用例，它里面包含了添加用户、修改用户信息、删除用户等操作，这些操作在该用例的事件流可以表述成为基本流的子事件流(subflow)。</p>
            <br />
            <img height="88" alt="" src="http://www.ibm.com/developerworks/cn/rational/r-usecase-atm/images/image040.gif" width="288" border="0" /> <br />
            <p>维护用户-基本事件流</p>
            <p>该基本流由三个子事件流构成：</p>
            <p>1) 添加用户子事件流 <br />
            &#8230; </p>
            <p>2) 修改用户 子事件流 <br />
            &#8230; </p>
            <p>3) 删除用户子事件流 <br />
            &#8230; </p>
            <p>但是你也可以根据该用例中的具体操作把它抽象成为三个用例，它所表示的系统需求和单个用例的模型是完全一样的。</p>
            <br />
            <img height="189" alt="" src="http://www.ibm.com/developerworks/cn/rational/r-usecase-atm/images/image042.gif" width="300" border="0" /> <br />
            <p>应该如何确定用例的粒度呢？在一次技术研讨会上，有人问起Ivar Jacoboson博士，一个系统需要有多少个用例？大师的回答是20个，当然他的意思是最好将用例模型的规模控制在几十个用例左右，这样比较容易来管理用例模型的复杂度。在用例个数大致确定的条件下，我们就很容易来确定用例粒度的大小。对于较复杂的系统，我们需要控制用例模型一级的复杂度，所以可以将复杂度适当地移往每一个用例的内部，也就是让一个用例包含较多的需求信息量。对于比较简单的系统，我们则可以将复杂度适度地曝露在模型一级，也就是我们可以将较复杂的用例分解成为多个用例。</p>
            <p>用例的粒度不但决定了用例模型级的复杂度，而且也决定了每一个用例内部的复杂度。我们应该根据每个系统的具体情况，因时因宜地来把握各个层次的复杂度，在尽可能保证整个用例模型的易理解性前提下决定用例的大小和数目。</p>
            <p><a name="N10475"><span class="smalltitle">5.3 用例图</span></a></p>
            <p>用例图的主要作用是描述参与者和用例之间的关系，简单的系统中只需要有一个用例图就可以把所有的关系都描述清楚。复杂的系统中可以有多个用例图，例如每个用例包都可以有一个独立的用例图来描述该用例包中所有的参与者和用例的关系。</p>
            <p>在一个用例模型中，如果参与者和用例之间存在着多对多的关系，并且他们之间的关系比较复杂，如果在同一个用例图中表述所有的参与者和用例就显得不够清晰，这时我们可创建多个用例图来分别表示各种关系。</p>
            <br />
            <img height="265" alt="" src="http://www.ibm.com/developerworks/cn/rational/r-usecase-atm/images/image044.gif" width="406" border="0" /> <br />
            <p>如果想要强调某一个参与者和多个用例的关系，你就可以以该参与者为中心，用一个用例图表述出该参与者和多个用例之间的关系。在这个用例图中，我们强调的是该参与者会使用系统所提供的哪些服务。</p>
            <br />
            <img height="228" alt="" src="http://www.ibm.com/developerworks/cn/rational/r-usecase-atm/images/image046.gif" width="308" border="0" /> <br />
            <p>如果想要强调某一个用例和多个参与者之间的关系，你就可以以该用例为中心，用一个用例图表述出该用例和多个参与者之间的关系。在这个用例图中，我们强调的是该用例会涉及到哪些参与者，或者说该用例所表示的系统服务有哪些使用者。</p>
            <br />
            <img height="203" alt="" src="http://www.ibm.com/developerworks/cn/rational/r-usecase-atm/images/image048.gif" width="369" border="0" /> <br />
            <p>总之在用例建模过程中，你可以根据自己的需要创建任意多个用例图，用不同的用例来强调参与者和用例之间不同的关系。但是最重要的是要考虑整个用例模型的可理解性，如果可以用一个用例图把意思表述清楚，就不要再用第二个，因为越是简洁的模型越易于理解。</p>
            <br />
            <br />
            <p><a name="resources"><span class="atitle">参考资料 </span></a></p>
            <ul>
                <li><a href="http://www.ibm.com/developerworks/cn/rational/r-usecase-atm/ATM.zip">样例代码</a> <br />
                <br />
                <br />
                <br />
                </li>
                <li>Jeffrey Friedl, Mastering Regular Expressions, O'Reilly<br />
                <br />
                </li>
                <li>Mendel Cooper, Advanced Bash-Scripting Guide<br />
                <br />
                </li>
                <li>Michael Jang, Mastering Redhat 9<br />
                </li>
            </ul>
            <br />
            <br />
            <p><a name="author"><span class="atitle">关于作者</span></a></p>
            <table cellspacing="0" cellpadding="0" width="100%" border="0">
                <tbody>
                    <tr>
                        <td colspan="3"><img height="5" alt="" src="http://www.ibm.com/i/c.gif" width="100%" /></td>
                    </tr>
                    <tr valign="top" align="left">
                        <td>
                        <p>&nbsp;</p>
                        </td>
                        <td><img height="5" alt="" src="http://www.ibm.com/i/c.gif" width="4" /></td>
                        <td width="100%">
                        <p>傅纯一，IBM中国有限公司软件部Rational中国区技术销售经理</p>
                        </td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table><img src ="http://www.blogjava.net/hulizhong/aggbug/258766.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hulizhong/" target="_blank">二胡</a> 2009-03-10 12:04 <a href="http://www.blogjava.net/hulizhong/archive/2009/03/10/258766.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>设计模式之Prototype(原型)</title><link>http://www.blogjava.net/hulizhong/archive/2009/03/09/258563.html</link><dc:creator>二胡</dc:creator><author>二胡</author><pubDate>Mon, 09 Mar 2009 03:00:00 GMT</pubDate><guid>http://www.blogjava.net/hulizhong/archive/2009/03/09/258563.html</guid><wfw:comment>http://www.blogjava.net/hulizhong/comments/258563.html</wfw:comment><comments>http://www.blogjava.net/hulizhong/archive/2009/03/09/258563.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/hulizhong/comments/commentRss/258563.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hulizhong/services/trackbacks/258563.html</trackback:ping><description><![CDATA[转&nbsp; http://www.jdon.com/designpatterns/prototype.htm<br />
<br />
<p>原型模式定义:<br />
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象.</p>
<p>Prototype模式允许一个对象再创建另外一个可定制的对象，根本无需知道任何如何创建的细节,工作原理是:通过将一个原型对象传给那个要发动创建的对象，这个要发动创建的对象通过请求原型对象拷贝它们自己来实施创建。</p>
<p>如何使用?<br />
因为Java中的提供clone()方法来实现对象的克隆,所以Prototype模式实现一下子变得很简单.</p>
<p>以勺子为例：</p>
<table cellspacing="3" cellpadding="3" width="96%" border="0">
    <tbody>
        <tr>
            <td bgcolor="#cccccc">public abstract class AbstractSpoon implements Cloneable<br />
            { <br />
            　　String spoonName; <br />
            <br />
            　　public void setSpoonName(String spoonName) {this.spoonName = spoonName;}<br />
            　　public String getSpoonName() {return this.spoonName;}<br />
            <br />
            　　public Object clone() <br />
            　　{<br />
            　　　　Object object = null;<br />
            　　　　try {<br />
            　　　　　　object = super.clone();<br />
            　　　　} catch (CloneNotSupportedException exception) {<br />
            　　　　　　System.err.println("AbstractSpoon is not Cloneable");<br />
            　　　　}<br />
            　　　　return object;<br />
            　　}<br />
            }<br />
            </td>
        </tr>
    </tbody>
</table>
<p>有个具体实现(ConcretePrototype):</p>
<table cellspacing="3" cellpadding="3" width="92%" border="0">
    <tbody>
        <tr>
            <td bgcolor="#cccccc">
            <p>public class SoupSpoon extends AbstractSpoon<br />
            { <br />
            　　public SoupSpoon()<br />
            　　{<br />
            　　　　setSpoonName("Soup Spoon"); <br />
            　　}<br />
            }<br />
            </p>
            <p>&nbsp; </p>
            </td>
        </tr>
    </tbody>
</table>
<p>调用Prototype模式很简单:</p>
<p>AbstractSpoon spoon = new SoupSpoon();<br />
AbstractSpoon spoon2 = spoon.clone(); </p>
<p>当然也可以结合工厂模式来创建AbstractSpoon实例。</p>
<p>在Java中Prototype模式变成clone()方法的使用，由于Java的纯洁的面向对象特性，使得在Java中使用设计模式变得很自然，两者已经几乎是浑然一体了。这反映在很多模式上，如Interator遍历模式。</p><img src ="http://www.blogjava.net/hulizhong/aggbug/258563.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hulizhong/" target="_blank">二胡</a> 2009-03-09 11:00 <a href="http://www.blogjava.net/hulizhong/archive/2009/03/09/258563.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>设计模式之Template</title><link>http://www.blogjava.net/hulizhong/archive/2009/03/09/258562.html</link><dc:creator>二胡</dc:creator><author>二胡</author><pubDate>Mon, 09 Mar 2009 02:55:00 GMT</pubDate><guid>http://www.blogjava.net/hulizhong/archive/2009/03/09/258562.html</guid><wfw:comment>http://www.blogjava.net/hulizhong/comments/258562.html</wfw:comment><comments>http://www.blogjava.net/hulizhong/archive/2009/03/09/258562.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/hulizhong/comments/commentRss/258562.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hulizhong/services/trackbacks/258562.html</trackback:ping><description><![CDATA[转 http://www.jdon.com/designpatterns/template.htm<br />
<br />
<p>Template模板模式定义:<br />
定义一个操作中算法的骨架,将一些步骤的执行延迟到其子类中.</p>
<p>使用Java的抽象类时，就经常会使用到Template模式,因此Template模式使用很普遍.而且很容易理解和使用。</p>
<p>&nbsp;</p>
<table cellspacing="3" cellpadding="3" width="80%" border="0">
    <tbody>
        <tr>
            <td bgcolor="#cccccc">public abstract class Benchmark<br />
            {<br />
            　　/**<br />
            　　* 下面操作是我们希望在子类中完成<br />
            　　*/<br />
            　　public abstract void benchmark();
            <p>　　/**<br />
            　　* 重复执行benchmark次数<br />
            　　*/<br />
            　　public final long repeat (int count) {<br />
            　　　　if (count &lt;= 0)<br />
            　　　　　　return 0;<br />
            　　　　else {<br />
            　　　　　　long startTime = System.currentTimeMillis();</p>
            <p>　　　　for (int i = 0; i &lt; count; i++) <br />
            　　　　　　benchmark();<br />
            <br />
            　　　　long stopTime = System.currentTimeMillis();<br />
            　　　　return stopTime - startTime;<br />
            　　}<br />
            }<br />
            }<br />
            </p>
            </td>
        </tr>
    </tbody>
</table>
<p>在上例中,我们希望重复执行benchmark()操作,但是对benchmark()的具体内容没有说明,而是延迟到其子类中描述:</p>
<table cellspacing="3" cellpadding="3" width="80%" border="0">
    <tbody>
        <tr>
            <td bgcolor="#cccccc">public class MethodBenchmark extends Benchmark<br />
            {<br />
            　　/**<br />
            　　* 真正定义benchmark内容<br />
            　　*/<br />
            　　public void benchmark() {<br />
            <br />
            　　　　for (int i = 0; i &lt; Integer.MAX_VALUE; i++){<br />
            　　　 　　System.out.printtln("i="+i);　 　　<br />
            　　　 }<br />
            　　}<br />
            }<br />
            </td>
        </tr>
    </tbody>
</table>
<p>至此,Template模式已经完成,是不是很简单?</p>
<p>我们称repeat方法为模板方法， 它其中的benchmark()实现被延迟到子类MethodBenchmark中实现了，</p>
<p>看看如何使用:</p>
<p>Benchmark operation = new MethodBenchmark();<br />
long duration = operation.repeat(Integer.parseInt(args[0].trim()));<br />
System.out.println("The operation took " + duration + " milliseconds");</p>
<p>&nbsp;</p>
<p>也许你以前还疑惑抽象类有什么用,现在你应该彻底明白了吧? 至于这样做的好处,很显然啊,扩展性强,以后Benchmark内容变化,我只要再做一个继承子类就可以,不必修改其他应用代码.</p><img src ="http://www.blogjava.net/hulizhong/aggbug/258562.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hulizhong/" target="_blank">二胡</a> 2009-03-09 10:55 <a href="http://www.blogjava.net/hulizhong/archive/2009/03/09/258562.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>小谈类的关联和依赖</title><link>http://www.blogjava.net/hulizhong/archive/2009/03/06/258156.html</link><dc:creator>二胡</dc:creator><author>二胡</author><pubDate>Fri, 06 Mar 2009 03:25:00 GMT</pubDate><guid>http://www.blogjava.net/hulizhong/archive/2009/03/06/258156.html</guid><wfw:comment>http://www.blogjava.net/hulizhong/comments/258156.html</wfw:comment><comments>http://www.blogjava.net/hulizhong/archive/2009/03/06/258156.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/hulizhong/comments/commentRss/258156.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hulizhong/services/trackbacks/258156.html</trackback:ping><description><![CDATA[２者的概念上的不同，网上有很多文章．我从代码实现上说说２者的不同<br />
　　关联：如果Ａ类的有个属性是Ｂ类型，那么Ａ和Ｂ就是关联关系（当然关联也分了几种：单向关联，双向关联）<br />
　　依赖：如果Ａ类的方法的参数或方法里的局部变量引用了Ｂ类，则是Ａ依赖Ｂ<br />
　　<br />
　　不对地方，大家说说！<img src ="http://www.blogjava.net/hulizhong/aggbug/258156.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hulizhong/" target="_blank">二胡</a> 2009-03-06 11:25 <a href="http://www.blogjava.net/hulizhong/archive/2009/03/06/258156.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>类的组合和类的聚合的区别</title><link>http://www.blogjava.net/hulizhong/archive/2009/03/06/258150.html</link><dc:creator>二胡</dc:creator><author>二胡</author><pubDate>Fri, 06 Mar 2009 03:07:00 GMT</pubDate><guid>http://www.blogjava.net/hulizhong/archive/2009/03/06/258150.html</guid><wfw:comment>http://www.blogjava.net/hulizhong/comments/258150.html</wfw:comment><comments>http://www.blogjava.net/hulizhong/archive/2009/03/06/258150.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/hulizhong/comments/commentRss/258150.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hulizhong/services/trackbacks/258150.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这2个概念不是很清楚,和朋友讨论了一下,把结果整理出来,希望对你有用!<br />
组合: 被拥有者是拥有者的一个组成部分.被拥有者的生命周期和拥有者的有强相关关系.也就是说当拥有者生命周期结束的时候,被拥有者也消亡了.常用于黑色实心菱形表示.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 例如:人死了,毛发也不存在了.<br />
聚合:表示事物的整体/部分关系的较弱情况,常用于空心实心菱形表示<br />
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 个人认为:做设计的时候,不要专注细节.呵呵,不知道观点对否?<img src ="http://www.blogjava.net/hulizhong/aggbug/258150.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hulizhong/" target="_blank">二胡</a> 2009-03-06 11:07 <a href="http://www.blogjava.net/hulizhong/archive/2009/03/06/258150.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>