ï»??xml version="1.0" encoding="utf-8" standalone="yes"?>丁香婷婷在线,波多野结衣在线观看一区二区三区,国产精品欧美极品http://www.aygfsteel.com/hulizhong/category/38139.html----Java's Slave----<br> ***Java's Host***zh-cnFri, 06 Nov 2009 01:41:35 GMTFri, 06 Nov 2009 01:41:35 GMT60设计模式å›?/title><link>http://www.aygfsteel.com/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.aygfsteel.com/hulizhong/archive/2009/11/03/300830.html</guid><wfw:comment>http://www.aygfsteel.com/hulizhong/comments/300830.html</wfw:comment><comments>http://www.aygfsteel.com/hulizhong/archive/2009/11/03/300830.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/hulizhong/comments/commentRss/300830.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/hulizhong/services/trackbacks/300830.html</trackback:ping><description><![CDATA[<img height="620" alt="" src="http://www.aygfsteel.com/images/blogjava_net/hulizhong/oo.jpg" width="527" border="0" /><img src ="http://www.aygfsteel.com/hulizhong/aggbug/300830.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/hulizhong/" target="_blank">二胡</a> 2009-11-03 09:40 <a href="http://www.aygfsteel.com/hulizhong/archive/2009/11/03/300830.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>大话之观察者模å¼?/title><link>http://www.aygfsteel.com/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.aygfsteel.com/hulizhong/archive/2009/07/07/285785.html</guid><wfw:comment>http://www.aygfsteel.com/hulizhong/comments/285785.html</wfw:comment><comments>http://www.aygfsteel.com/hulizhong/archive/2009/07/07/285785.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.aygfsteel.com/hulizhong/comments/commentRss/285785.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/hulizhong/services/trackbacks/285785.html</trackback:ping><description><![CDATA[<p>      å¤§å®¶éƒ½çŸ¥é“,毛主席对游击战有个十六字诀åQ?敌进我退åQŒæ•Œé©ÀLˆ‘扎ͼŒæ•Œç–²æˆ‘打åQŒæ•Œé€€æˆ‘追"ã€?br /> 我对此的理解ž®±æ˜¯å½“敌人的形势发生了变化,我们行动也要相应变动。其实在软äšg开发过½E‹ä¸­ä¹Ÿæœ‰¾cÕd¼æƒ…景。当A对象的状态变化的时候,B对象的状态也要相应变化。我们常用观察者模式解å†Ïx­¤¾c»é—®é¢˜ã€‚代码如ä¸?可能和大家åã^å¸¸è§çš„è§‚å¯Ÿè€…æ¨¡å¼çš„ä»£ç å®žçŽ°ä¸å¤ªä¸€æ øP¼Œå…¶å®žåŽŸç†éƒ½æ˜¯ä¸€æ ïLš„ã€?br />     åœ¨ä¸‹é¢çš„代码里,我方的情报äh员显的很重要ã€?span style="color: red">卌™¢«è§‚察者要有到观察者的引用ã€?/span></p> <p> public class 敌äh {<br />  private æˆ?my;</p> <p> public 敌äh() {<br />   my = new æˆ?); /* 哈哈,敌äh内部的我æ–ÒŽƒ…报ähå‘?*/<br />  }</p> <p> public void ˜q?) {<br />   System.out.println("--敌进--");<br />   my.退();<br />  }</p> <p> public void é©?) {<br />   System.out.println("--敌驻--");<br />   my.æ‰?);<br />  }</p> <p> public void ç–?) {<br />   System.out.println("--敌疲--");<br />   my.æ‰?);<br />  }</p> <p> public void 退() {<br />   System.out.println("--敌退--");<br />   my.˜q?);<br />  }<br /> }</p> <p><br />  public class æˆ?{<br />  public void 退() {<br />   System.out.println("--我退--");<br />  }</p> <p> public void æ‰?) {<br />   System.out.println("--我扰--");<br />  }</p> <p> public void æ‰?) {<br />   System.out.println("--我打--");<br />  }</p> <p> public void ˜q?) {<br />   System.out.println("--我追--");<br />  }<br /> }</p> <p> </p><img src ="http://www.aygfsteel.com/hulizhong/aggbug/285785.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/hulizhong/" target="_blank">二胡</a> 2009-07-07 12:34 <a href="http://www.aygfsteel.com/hulizhong/archive/2009/07/07/285785.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>深入‹¹…出单实例Singleton设计模式http://www.aygfsteel.com/hulizhong/archive/2009/07/06/285685.html二胡二胡Mon, 06 Jul 2009 06:25:00 GMThttp://www.aygfsteel.com/hulizhong/archive/2009/07/06/285685.htmlhttp://www.aygfsteel.com/hulizhong/comments/285685.htmlhttp://www.aygfsteel.com/hulizhong/archive/2009/07/06/285685.html#Feedback0http://www.aygfsteel.com/hulizhong/comments/commentRss/285685.htmlhttp://www.aygfsteel.com/hulizhong/services/trackbacks/285685.html
深入‹¹…出单实例Singleton设计模式

陈皓

前序

单实例Singleton设计模式可能是被讨论和ä‹É用的最òq¿æ³›çš„一个设计模式了åQŒè¿™å¯èƒ½ä¹Ÿæ˜¯é¢è¯•中问得最多的一个设计模式了。这个设计模式主要目çš? 是想在整个系¾lŸä¸­åªèƒ½å‡ºçŽ°ä¸€ä¸ªç±»çš„å®žä¾‹ã€‚è¿™æ ·åšå½“ç„¶æ˜¯æœ‰å¿…ç„¶çš„ï¼Œæ¯”å¦‚ä½ çš„è½¯äšg的全局配置信息åQŒæˆ–者是一个FactoryåQŒæˆ–是一个主控类åQŒç­‰½{‰ã€‚你希望˜q? 个类在整个系¾lŸä¸­åªèƒ½å‡ºçŽ°ä¸€ä¸ªå®žä¾‹ã€‚å½“ç„Óž¼Œä½œäؓ一个技术负责äh的你åQŒä½ å½“然有权利通过使用非技术的手段来达åˆîC½ çš„目的。比如:你在团队内部明文è§? 定,“XX¾cÕdªèƒ½æœ‰ä¸€ä¸ªå…¨å±€å®žä¾‹åQŒå¦‚果某äºÞZ‹É用两‹Æ¡ä»¥ä¸Šï¼Œé‚£ä¹ˆè¯¥ähž®†è¢«å¤„于2000元的¾|𿬾åQ?#8221;åQˆå‘µå‘µï¼‰åQŒä½ å½“然有权˜q™ä¹ˆåšã€‚但是如果你的设计的是东西是 一个类库,或是一个需要提供给用户使用的APIåQŒææ€•你的这™å¹è§„定将会失效。因为,你无权要求别äºÞZ¼šé‚£ä¹ˆåšã€‚所以,˜q™å°±æ˜¯äؓ什么,我们希望通过使用技术的 手段来达成这样一个目的的原因ã€?/p>

本文会带着你深入整个Singleton的世界,当然åQŒæˆ‘会放弃ä‹É用C++语言而改用Java语言åQŒå› ä¸ÞZ‹É用Java˜q™ä¸ªè¯­è¨€å¯èƒ½æ›´å®¹æ˜“让我说明一些事情ã€?/p>


Singleton的教学版�/h1>

˜q™é‡ŒåQŒæˆ‘ž®†ç›´æŽ¥ç»™å‡ÞZ¸€ä¸ªSingleton的简单实玎ͼŒå› äؓ我相信你已经有这斚w¢çš„一些基¼‹€äº†ã€‚我们姑且把˜q™å…·ç‰ˆæœ¬å«åš1.0ç‰?/p>

  1. // version 1.0   
  2. public class Singleton   
  3. {   
  4.     private static final Singleton singleton = null;   
  5.   
  6.     private Singleton()   
  7.     {   
  8.     }   
  9.     public static Singleton getInstance()   
  10.     {   
  11.         if (singleton== null)   
  12.         {   
  13.             singleton= new Singleton();   
  14.         }   
  15.         return singleton;   
  16.     }   
  17. }  

在上面的实例中,我想说明下面几个Singleton的特点:åQˆä¸‹é¢è¿™äº›ä¸œè¥¿å¯èƒ½æ˜¯ž®½äh皆知的,没有什么新鲜的åQ?/p>

  1. ¿Uæœ‰åQˆprivateåQ‰çš„æž„造函敎ͼŒè¡¨æ˜Ž˜q™ä¸ª¾cÀL˜¯ä¸å¯èƒ½åŞ成实例了。这主要是怕这个类会有多个实例ã€?
  2. 即然˜q™ä¸ª¾cÀL˜¯ä¸å¯èƒ½åŞ成实例,那么åQŒæˆ‘们需要一个静态的方式让其形成实例åQšgetInstance()。注意这个方法是在new自己åQŒå› ä¸ºå…¶å¯ä»¥è®‰K—®¿Uæœ‰çš„æž„造函敎ͼŒæ‰€ä»¥ä»–是可以保证实例被创徏出来的ã€?
  3. 在getInstance()中,先做判断是否已åŞ成实例,如果已åŞ成则直接˜q”回åQŒå¦åˆ™åˆ›å»ºå®žä¾‹ã€?
  4. 所形成的实例保存在自己¾cÖM¸­çš„私有成员中ã€?
  5. 我们取实例时åQŒåªéœ€è¦ä‹É用Singleton.getInstance()ž®Þp¡Œäº†ã€?

当然åQŒå¦‚果你觉得知道了上面这些事情后ž®±å­¦æˆäº†åQŒé‚£æˆ‘给你当头棒喝一下了åQŒäº‹æƒ…远˜qœæ²¡æœ‰é‚£ä¹ˆç®€å•ã€?/p>

Singleton的实际版�/h1>

上面的这个程序存在比较严重的问题åQŒå› ä¸ºæ˜¯å…¨å±€æ€§çš„实例åQŒæ‰€ä»¥ï¼Œåœ¨å¤š¾U¿ç¨‹æƒ…况下,所有的全局å…׃ín的东襉Kƒ½ä¼šå˜å¾—非常的危险åQŒè¿™ä¸ªä¹Ÿä¸€æ øP¼Œåœ¨å¤š¾U¿ç¨‹æƒ? 况下åQŒå¦‚果多个线½E‹åŒæ—¶è°ƒç”¨getInstance()的话åQŒé‚£ä¹ˆï¼Œå¯èƒ½ä¼šæœ‰å¤šä¸ª˜q›ç¨‹åŒæ—¶é€šè¿‡ (singleton== null)的条件检查,于是åQŒå¤šä¸ªå®žä¾‹å°±åˆ›å¾å‡ºæ¥åQŒåƈ且很可能造成内存泄露问题。嗯åQŒç†Ÿæ‚‰å¤š¾U¿ç¨‹çš„你一定会说—â€?#8220;我们需要线½E‹äº’斥或同步”åQŒæ²¡é”™ï¼Œæˆ‘们 需要这个事情,于是我们的Singleton升çñ”æˆ?.1版,如下所½Cºï¼š

  1. // version 1.1   
  2. public class Singleton   
  3. {   
  4.     private static final Singleton singleton = null;   
  5.   
  6.     private Singleton()   
  7.     {   
  8.     }   
  9.     public static Singleton getInstance()   
  10.     {   
  11.         if (singleton== null)   
  12.         {   
  13.             synchronized (Singleton.class) {   
  14.                 singleton= new Singleton();   
  15.             }   
  16.         }   
  17.         return singleton;   
  18.     }   
  19. }  

嗯,使用了Javaçš„synchronizedæ–ÒŽ³•åQŒçœ‹èµäh¥ä¸é”™å“¦ã€‚应该没有问题了吧?åQé”™åQè¿™˜q˜æ˜¯æœ‰é—®é¢˜ï¼ä¸ÞZ»€ä¹ˆå‘¢åQŸå‰é¢å·²¾lè¯´˜q‡ï¼Œå¦‚果有多个线 ½E‹åŒæ—‰™€šè¿‡(singleton== null)çš„æ¡ä»¶æ£€æŸ¥ï¼ˆå› äØ“ä»–ä»¬òq¶è¡Œ˜qè¡ŒåQ‰ï¼Œè™½ç„¶æˆ‘们的synchronizedæ–ÒŽ³•会帮助我们同步所有的¾U¿ç¨‹åQŒè®©æˆ‘们òq¶è¡Œ¾U¿ç¨‹å˜æˆä¸²è¡Œçš„一个一个去 newåQŒé‚£ä¸è¿˜æ˜¯ä¸€æ ïLš„吗?同样会出现很多实例。嗯åQŒç¡®å®žå¦‚此!看来åQŒè¿˜å¾—把那个判断(singleton== null)条äšg也同步è“v来。于是,我们的Singleton再次升çñ”æˆ?.2版本åQŒå¦‚下所½Cºï¼š

 
  1. // version 1.2   
  2. public class Singleton   
  3. {   
  4.     private static final Singleton singleton = null;   
  5.   
  6.     private Singleton()   
  7.     {   
  8.     }   
  9.     public static Singleton getInstance()   
  10.     {   
  11.         synchronized (Singleton.class)   
  12.         {   
  13.             if (singleton== null)   
  14.             {   
  15.                 singleton= new Singleton();   
  16.             }   
  17.         }   
  18.         return singleton;   
  19.     }   
  20. }  

不错不错åQŒçœ‹ä¼¼å¾ˆä¸é”™äº†ã€‚在多线½E‹ä¸‹åº”该没有什么问题了åQŒä¸æ˜¯å—åQŸçš„¼‹®æ˜¯˜q™æ ·çš„,1.2版的Singleton在多¾U¿ç¨‹ä¸‹çš„¼‹®æ²¡æœ‰é—®é¢˜äº†åQŒå› ä¸ºæˆ‘ä»? 同步了所有的¾U¿ç¨‹ã€‚只不过å˜?#8230;…åQŒä»€ä¹ˆï¼ŸåQè¿˜ä¸è¡ŒåQŸï¼æ˜¯çš„åQŒè¿˜æ˜¯æœ‰ç‚¹å°é—®é¢˜åQŒæˆ‘们本来只是想让new˜q™ä¸ªæ“ä½œòq¶è¡Œž®±å¯ä»¥äº†åQŒçŽ°åœ¨ï¼Œåªè¦æ˜¯è¿›å…? getInstance()的线½E‹éƒ½å¾—同步啊åQŒæ³¨æ„ï¼Œåˆ›å¾å¯¹è±¡çš„动作只有一‹Æ¡ï¼ŒåŽé¢çš„动作全是读取那个成员变量,˜q™äº›è¯Õd–的动作不需要线½E‹åŒæ­¥å•Šã€‚è¿™æ ïLš„ 作法感觉非常极端啊,ä¸ÞZº†ä¸€ä¸ªåˆå§‹åŒ–的创建动作,居然让我们达上了所有的è¯ÀL“ä½œï¼Œä¸¥é‡å½±å“åŽç®‹çš„æ€§èƒ½å•Šï¼

˜q˜å¾—改!嗯,看来åQŒåœ¨¾U¿ç¨‹åŒæ­¥å‰è¿˜å¾—加一ä¸?singleton== null)的条件判断,如果对象已经创徏了,那么ž®×ƒ¸éœ€è¦çº¿½E‹çš„同步了。OKåQŒä¸‹é¢æ˜¯1.3版的Singletonã€?/p>

  1. // version 1.3   
  2. public class Singleton   
  3. {   
  4.     private static final Singleton singleton = null;   
  5.   
  6.     private Singleton()   
  7.     {   
  8.     }   
  9.     public static Singleton getInstance()   
  10.     {   
  11.         if (singleton== null)   
  12.         {   
  13.             synchronized (Singleton.class)   
  14.             {   
  15.                 if (singleton== null)   
  16.                 {   
  17.                     singleton= new Singleton();   
  18.                 }   
  19.             }   
  20.         }   
  21.         return singleton;   
  22.     }   
  23. }  

感觉代码开始变得有点罗嗦和复杂了,不过åQŒè¿™å¯èƒ½æ˜¯æœ€ä¸é”™çš„一个版本了åQŒè¿™ä¸ªç‰ˆæœ¬åˆå?#8220;双重‹‚€æŸ?#8221;Double-Check。下面是说明åQ?/p>

  1. ½W¬ä¸€ä¸ªæ¡ä»¶æ˜¯è¯ß_¼Œå¦‚果实例创徏了,那就不需要同步了åQŒç›´æŽ¥è¿”回就好了ã€?
  2. 不然åQŒæˆ‘们就开始同步线½E‹ã€?
  3. ½W¬äºŒä¸ªæ¡ä»¶æ˜¯è¯ß_¼Œå¦‚果被同步的¾U¿ç¨‹ä¸­ï¼Œæœ‰ä¸€ä¸ªçº¿½E‹åˆ›å»ÞZº†å¯¹è±¡åQŒé‚£ä¹ˆåˆ«çš„线½E‹å°±ä¸ç”¨å†åˆ›å»ÞZº†ã€?

相当不错啊,òq²å¾—非常漂亮åQè¯·å¤§å®¶ä¸ºæˆ‘们的1.3版è“v立鼓掌!

Singleton的其它问�/h1>

怎么åQŸè¿˜æœ‰é—®é¢˜ï¼ŸåQå½“然还有,误‚®°ä½ä¸‹é¢è¿™æ¡è§„则—â€?#8220;无论你的代码写得有多好,其只能在特定的范围内工作åQŒè¶…凸™¿™ä¸ªèŒƒå›´å°±è¦å‡ºBugäº?/strong>”åQŒè¿™æ˜?#8220;陈式½W¬ä¸€å®šç†”åQŒå‘µå‘üc€‚你能想一惌™¿˜æœ‰ä»€ä¹ˆæƒ…况会让这个我们上面的代码出问题吗åQ?/p>

在C++下,我不是很好ä‹D例,但是在Java的环境下åQŒå˜¿å˜¿ï¼Œ˜q˜æ˜¯è®©æˆ‘们来看看下面的一些反例和一些别的事情的讨论åQ?strong>当然åQŒæœ‰äº›åä¾‹å¯èƒ½å±žäºŽé’»ç‰›è§’ž®–,可能有点学院‹z¾ï¼Œä¸è¿‡ä¹Ÿä¸æŽ’除其实际可能性,ž®Þq®—是提个醒å?/strong>åQ‰ï¼š

其一、Class Loader。不知道你对Javaçš„Class Loader熟悉吗?“¾c»è£…载器”åQŸï¼C++可没有这个东西啊。这是Java动态性的核心。顾名思义åQŒç±»è£…蝲器是用来把类(class)装蝲˜q›JVMçš„ã€? JVM规范定义了两¿Uç±»åž‹çš„¾c»è£…载器åQšå¯åŠ¨å†…è£…è²å™?bootstrap)和用戯‚‡ªå®šä¹‰è£…蝲å™?user-defined class loader)ã€? 在一个JVM中可能存在多个ClassLoaderåQŒæ¯ä¸ªClassLoader拥有自己的NameSpace。一个ClassLoader只能拥有一ä¸? class对象¾cÕdž‹çš„实例,但是不同的ClassLoader可能拥有相同的class对象实例åQŒè¿™æ—¶å¯èƒ½äñ”生致命的问题。如ClassLoaderAåQ? 装蝲了类A的类型实例A1åQŒè€ŒClassLoaderBåQŒä¹Ÿè£…蝲了类A的对象实例A2。逻辑上讲A1=A2åQŒä½†æ˜¯ç”±äºŽA1å’ŒA2来自于不同的 ClassLoaderåQŒå®ƒä»¬å®žé™…上是完全不同的åQŒå¦‚æžœA中定义了一个静态变量cåQŒåˆ™c在不同的ClassLoader中的值是不同的ã€?/p>

于是åQŒå¦‚果咱们的Singleton 1.3版本如果面对着多个Class Loaderä¼šæ€Žä¹ˆæ øP¼Ÿå‘µå‘µåQŒå¤šä¸ªå®žä¾‹åŒæ ·ä¼šè¢«å¤šä¸ªClass Loader创徏出来åQŒå½“ç„Óž¼Œ˜q™ä¸ªæœ‰ç‚¹ç‰µå¼ºåQŒä¸˜q‡ä»–¼‹®å®žå­˜åœ¨ã€‚难道我们还要整å‡ÞZ¸ª1.4版吗åQŸå¯æ˜¯ï¼Œæˆ‘们怎么可能在我的Singleton¾cÖM¸­æ“ä½œ Class Loader啊?是的åQŒä½ æ ÒŽœ¬ä¸å¯èƒ½ã€‚在˜q™ç§æƒ…况下,你能做的只有是—â€?#8220;保证多个Class Loader不会装蝲同一个Singleton”ã€?/p>

其二、序例化ã€?/strong>如果我们的这个Singleton¾cÀL˜¯ä¸€ä¸ªå…³äºŽæˆ‘们程序配¾|®ä¿¡æ¯çš„¾c…R€‚我们需要它有序列化的功能,那么åQŒå½“反序列化的时候,我们ž®†æ— æ³•控制别äºÞZ¸å¤šæ¬¡ååºåˆ—化。不˜q‡ï¼Œæˆ‘们可以利用一下Serializable接口的readResolve()æ–ÒŽ³•åQŒæ¯”如:

  1. public class Singleton implements Serializable   
  2. {   
  3.     ......   
  4.     ......   
  5.     protected Object readResolve()   
  6.     {   
  7.         return getInstance();   
  8.     }   
  9. }  

其三、多个Java虚拟机ã€?/strong>如果我们的程序运行在多个Java的虚拟机中。什么?多个虚拟机?˜q™æ˜¯ä¸€¿Uä»€ä¹ˆæ ·çš„æƒ…况啊。嗯åQŒè¿™¿Uæƒ…冉|˜¯æœ‰ç‚¹æžç«¯åQŒä¸˜q‡è¿˜æ˜¯å¯èƒ½å‡ºçŽŽÍ¼Œæ¯”如EJB或RMI之流的东è¥Ñ€‚要在这¿UçŽ¯å¢ƒä¸‹é¿å…å¤šå®žä¾‹ï¼Œçœ‹æ¥åªèƒ½é€šè¿‡è‰¯å¥½çš„è®¾è®¡æˆ–éžæŠ€æœ¯æ¥è§£å†³äº†ã€?/p>

å…¶å››åQŒvolatile变量ã€?/strong>关于volatile˜q™ä¸ªå…³é”®å­—所声明的变量可以被看作是一¿U? “½E‹åº¦è¾ƒè½»çš„同步synchronized”åQ›ä¸Ž synchronized 块相比,volatile 变量所需的编码较ž®‘,òq¶ä¸”˜qè¡Œæ—¶å¼€é”€ä¹Ÿè¾ƒž®‘,但是它所能实现的功能也仅是synchronized的一部分。当ç„Óž¼Œå¦‚前面所˜qŽÍ¼Œæˆ‘们需要的 Singleton只是在创建的时候线½E‹åŒæ­¥ï¼Œè€ŒåŽé¢çš„è¯Õd–则不需要同步。所以,volatile变量òq¶ä¸èƒ½å¸®åŠ©æˆ‘ä»¬å³èƒ½è§£å†³é—®é¢˜ï¼Œåˆæœ‰å¥½çš„æ€§èƒ½ã€‚è€Œä¸”åQ? ˜q™ç§å˜é‡åªèƒ½åœ¨JDK 1.5+版后才能使用ã€?/p>

其五、关于ç‘ôæ‰Ñ€?/strong>是的åQŒç‘ô承于Singleton后的子类也有可能造成多实例的问题。不˜q‡ï¼Œå› äؓ我们早把Singleton的构造函数声明成了私有的åQŒæ‰€ä»¥ä¹Ÿž®±æœ¾läº†¾l§æ‰¿˜q™ç§äº‹æƒ…ã€?/p>

å…¶å…­åQŒå…³äºŽä»£ç é‡ç”¨ã€?/strong>也话我们的系¾lŸä¸­æœ‰å¾ˆå¤šä¸ª¾c»éœ€è¦ç”¨åˆ°è¿™ä¸ªæ¨¡å¼ï¼Œå¦‚果我们在每一个类都中有这æ ïLš„代码åQŒé‚£ä¹? ž®±æ˜¾å¾—有点傻了。那么,我们是否可以使用一¿Uæ–¹æ³•,把这å…äh¨¡å¼æŠ½è±¡å‡ºåŽ»ï¼Ÿåœ¨C++下这是很å®ÒŽ˜“çš„ï¼Œå› äØ“æœ‰æ¨¡æ¿å’Œå‹å…ƒåQŒè¿˜æ”¯æŒæ ˆä¸Šåˆ†é…å†…å­˜åQŒæ‰€ä»¥æ¯”较容易一 些(½E‹åºå¦‚下所½Cºï¼‰åQŒJava下可能比较复杂一些,聪明的你知道怎么做吗åQ?/p>

  1. template<CLASS T> class Singleton   
  2. {   
  3.     public:   
  4.         static T& Instance()   
  5.         {   
  6.             static T theSingleInstance; //假设T有一个protected默认构造函æ•?  
  7.             return theSingleInstance;   
  8.         }   
  9. };   
  10.   
  11. class OnlyOne : public Singleton<ONLYONE>   
  12. {   
  13.     friend class Singleton<ONLYONE>;   
  14.     int example_data;   
  15.   
  16.     public:   
  17.         int GetExampleData() const {return example_data;}   
  18.     protected:   
  19.         OnlyOne(): example_data(42) {}   // é»˜è®¤æž„造函æ•?  
  20.         OnlyOne(OnlyOne&) {}   
  21. };   
  22.   
  23. int main( )   
  24. {   
  25.     cout << OnlyOne::Instance().GetExampleData()<< endl;   
  26.     return 0;   
  27. }  

 (转蝲时请注明作者和出处。未¾lè®¸å¯ï¼Œè¯·å‹¿ç”¨äºŽå•†ä¸šç”¨é€?/span>)

åQˆå…¨æ–‡å®ŒåQ?/p>



]]>è½?UML建模的要ç‚ÒŽ€È»“http://www.aygfsteel.com/hulizhong/archive/2009/04/15/265779.html二胡二胡Wed, 15 Apr 2009 08:12:00 GMThttp://www.aygfsteel.com/hulizhong/archive/2009/04/15/265779.htmlhttp://www.aygfsteel.com/hulizhong/comments/265779.htmlhttp://www.aygfsteel.com/hulizhong/archive/2009/04/15/265779.html#Feedback0http://www.aygfsteel.com/hulizhong/comments/commentRss/265779.htmlhttp://www.aygfsteel.com/hulizhong/services/trackbacks/265779.html

UML建模的要ç‚ÒŽ€È»“

2009-03-18 11:57作者:出处åQšå¤©æžç½‘è´£ä“Q¾~–辑åQšéƒ‘é‡?/span>

  预备知识åQ?/p>

  一、UML的特性与发展现状

  UML是一¿ULanguage(语言)

  UML是一¿UModeling(建模)Language

  UML是Unified(¾lŸä¸€)Modeling Language

  1、已˜q›å…¥å…¨é¢åº”用阶段的事实标å‡?/p>

  2、应用领域正在逐渐扩展åQŒåŒ…括嵌入式¾pȝ»Ÿå»ºæ¨¡ã€ä¸šåŠ¡å¾æ¨¡ã€æµ½E‹å¾æ¨¡ç­‰å¤šä¸ªé¢†åŸŸ

  3、成ä¸?#8220;产生式编½E?#8221;的重要支持技术:MDAã€?可执行UML½{?/p>

  二、徏模的目的与原�/p>

  1、帮助我们按照实际情冉|ˆ–按我们需要的样式对系¾lŸè¿›è¡Œå¯è§†åŒ–;提供一¿Uè¯¦¾l†è¯´æ˜Žç³»¾lŸçš„¾l“构或行为的æ–ÒŽ³•;¾l™å‡ºä¸€ä¸ªæŒ‡å¯¼ç³»¾lŸæž„造的模板;å¯ÒŽˆ‘们所做出的决½{–进行文档化ã€?/p>

  2、仅当需要模型时åQŒæ‰æž„徏它ã€?/p>

  3、选择要创å»ÞZ»€ä¹ˆæ¨¡åž‹å¯¹å¦‚何动手解决问题和如何åŞ成解å†Ïx–¹æ¡ˆæœ‰ç€æ„ä¹‰æ·Þp¿œçš„媄å“?每一¿Uæ¨¡åž‹å¯ä»¥åœ¨ä¸åŒçš„精度çñ”别上表示;最好的模型是与现实相联¾pȝš„;单个模型是不充分的。对每个重要的系¾lŸæœ€å¥½ç”¨ä¸€¾l„几乎独立的模型åŽÕd¤„理ã€?/p>

  三、谁应该建模

  1ã€ä¸šåŠ¡å¾æ¨¡ï¼šä»¥é¢†åŸŸä¸“å®¶äØ“ä¸»ï¼Œéœ€æ±‚åˆ†æžäh员是ä¸ÕdŠ›åQŒç³»¾lŸåˆ†æžå‘˜ã€æž¶æž„师可参ä¸?/p>

  2、需求模型:以需求分析ähå‘˜äØ“ä¸»ï¼Œ¾pȝ»Ÿåˆ†æžå‘˜æ˜¯ä¸ÕdŠ›åQŒé¢†åŸŸä¸“家提供指å¯û|¼Œæž¶æž„师和资深开发äh员参ä¸?/p>

  3、设计模型:高层设计模型以架构师ä¸ÞZ¸»åQŒç³»¾lŸåˆ†æžå‘˜ä»Žéœ€æ±‚方面提供支持,资深开发äh员从技术实现方面提供支持。详¾l†è®¾è®¡æ¨¡åž‹åˆ™ä»¥èµ„深开发ähå‘˜äØ“ä¸»ï¼Œæž¶æž„å¸ˆæä¾›æŒ‡å¯¹{€?/p>

  4、实现模型:以资深开发ähå‘?设计人员)ä¸ÞZ¸»åQŒæž¶æž„师提供æ€ÖM½“指导ã€?/p>

  5ã€?a class="fllink" target="_bank">数据åº?/a>模型åQšä»¥æ•°æ®åº“开发ähå‘˜äØ“ä¸»ï¼Œæž¶æž„å¸ˆæä¾›æŒ‡å¯û|¼Œèµ„深开发ähå‘?设计人员)予以配合ã€?/p>

  正式开�/p>

  UML¾l„成åQŒä¸‰éƒ¨åˆ†(构造块、规则、公共机åˆ?åQŒå…³¾pÕd¦‚下图所½Cºï¼š

  

  一、构造块

  1、构造块是对模型中最å…ähœ‰ä»£è¡¨æ€§çš„æˆåˆ†çš„æŠ½è±?/p>

  建模元素åQšUML中的名词åQŒå®ƒæ˜¯æ¨¡åž‹åŸºæœ¬ç‰©ç†å…ƒç´ ã€?/p>

ã€€ã€€è¡ŒäØ“å…ƒç´ åQšUML中的动词åQŒå®ƒæ˜¯æ¨¡åž‹ä¸­çš„动态部分,是一¿Uè·¨­‘Šæ—¶é—´ã€ç©ºé—´çš„è¡ŒäØ“ã€?/p>

  分组元素åQšUML中的容器åQŒç”¨æ¥ç»„¾l‡æ¨¡åž‹ï¼Œä½¿æ¨¡åž‹æ›´åŠ çš„¾l“构化ã€?/p>

  注释元素åQšUML中的解释部分åQŒå’Œä»£ç ä¸­çš„æ³¨é‡Šè¯­å¥ä¸€æ øP¼Œæ˜¯ç”¨æ¥æ˜q°æ¨¡åž‹çš„ã€?/p>

  1.1、徏模元�/p>

  ¾c?class)和对è±?object)

  接口(interface)

  ä¸ÕdЍ¾c?active class)

  用例(use case)

  协作(collaboration)

  构äšg(component)

  节点(node)

  ¾c?class)和对è±?object)

  ¾cÀL˜¯å¯¹ä¸€¾l„具有相同属性、相同操作、相同关¾pÕd’Œç›¸åŒè¯­ä¹‰çš„对象的抽象

  UML中类是用一个矩形表½Cºçš„åQŒå®ƒåŒ…含三个区域åQŒæœ€ä¸Šé¢æ˜¯ç±»åã€ä¸­é—´æ˜¯¾cȝš„属性、最下面是类的方æ³?/p>

  对象则是¾cȝš„一个实ä¾?(object is a Instance of Class)

  接口(interface)

  接口是描˜q°æŸä¸ªç±»æˆ–构件的一个服务操作集

  ä¸ÕdЍ¾c?active class)

  ä¸ÕdЍ¾cÕd®žé™…上是一¿Uç‰¹ŒDŠçš„¾c…R€‚引用它的原因,实际上是在开发中需要有一些类能够起到 启动控制‹zÕdŠ¨çš„ä½œç”?/p>

  ä¸ÕdЍ¾cÀL˜¯æŒ‡å…¶å¯¹è±¡è‡›_°‘拥有一个进 ½E‹æˆ–¾U¿ç¨‹åQŒèƒ½å¤Ÿå¯åŠ¨æŽ§åˆ¶æ´»åŠ¨çš„¾c?/p>

  用例(use case)

  用例是著名的大师Ivar Jacobson首先提出的,现已¾læˆä¸ÞZº†é¢å‘对象软äšg开发中一个需求分析的最常用工具

  用例实例是在¾pȝ»Ÿä¸­æ‰§è¡Œçš„一¾pÕdˆ—动作åQŒè¿™äº›åŠ¨ä½œå°†ç”Ÿæˆç‰¹å®šæ‰§è¡Œè€…å¯è§çš„ä»·å€¼ç»“æžœã€‚ä¸€ä¸?用例定义一¾l„用例实例ã€?/p>

  协作(collaboration)

  协作定义了一个交互,它是ç”׃¸€¾l„共同工作以提供某协作行为的角色和其他元素构 成的一个群体ã€?/p>

  对于某个用例的实现就å?以表½CÞZؓ一个协ä½?/p>

  构äšg(component)

  在实际的软äšg¾pȝ»Ÿä¸­ï¼Œæœ‰è®¸å¤šè¦æ¯?#8220;¾c?#8221;更大的实体,例如一个COM¾l„äšg、一个DLLæ–‡äšg、一个JavaBeans、一个执行文件等½{‰ã€‚äØ“äº†æ›´å¥½åœ°å¯¹åœ¨UML模型中对它们˜q›è¡Œè¡¨ç¤ºåQŒå°±å¼•入了构ä»?也译为组ä»?

  构äšg是系¾lŸè®¾è®¡çš„一个模块化部分åQŒå®ƒéšè—äº†å†…部的实现åQŒå¯¹å¤–提供了一¾l„外部接口。在¾pȝ»Ÿä¸­æ»¡­‘³ç›¸åŒæŽ¥å£çš„¾l„äšg可以自由地替æ?/p>

  节点(node)

  ä¸ÞZº†èƒ½å¤Ÿæœ‰æ•ˆåœ°å¯¹éƒ¨çÖv的结构进行徏模,UML引入了节点这一概念åQŒå®ƒå¯ä»¥ç”¨æ¥æè¿°å®žé™…çš„PC机、打印机ã€?a class="fllink" target="_bank">服务å™?/a>½{‰èÊY件运行的基础¼‹¬äšg

  节点是运行时存在的物理元素,它表½CÞZº†ä¸€¿Uå¯è®¡ç®—的资源,通常臛_°‘有存储空间和处理能力

  1.2、行为元�/p>

  交互(interaction)åQ?是在特定语境中,共同完成某个ä»ÕdŠ¡çš„ä¸€¾l„对象之间交换的信息集合

  交互的表½Cºæ³•很简单,ž®±æ˜¯ä¸€æ¡æœ‰å‘ç›´¾U¿ï¼Œòq¶åœ¨ä¸Šé¢æ ‡æœ‰æ“ä½œå?/p>

  状态机(state machine)åQšæ˜¯ä¸€ä¸ªå¯¹è±¡æˆ–äº¤äº’åœ¨ç”Ÿå‘½å‘¨æœŸå†…å“åº”äº‹äšg所¾låŽ†çš„çŠ¶æ€åºåˆ?/p>

  在UML模型中将状态画ä¸ÞZ¸€ä¸ªåœ† 角矩形,òq¶åœ¨çŸ©åŞ内写出状态名 ¿U°åŠå…¶å­çжæ€?/p>

  1.3、分¾l„å…ƒç´?/p>

  对于一个中大型的èÊYä»¶ç³»¾lŸè€Œè¨€åQŒé€šå¸¸ä¼šåŒ…含大量的¾c»ï¼Œå› æ­¤ä¹Ÿå°±ä¼šå­˜åœ¨å¤§é‡çš„¾l“构事物、行ä¸ÞZº‹ç‰©ï¼Œä¸ÞZº†èƒ½å¤Ÿæ›´åŠ æœ‰æ•ˆåœ°å¯¹å…¶è¿›è¡Œæ•´åˆï¼Œç”Ÿæˆæˆ–ç®€æˆ–ç¹ã€æˆ–å®è§‚æˆ–å¾®è§‚çš„æ¨¡åž‹åQŒå°±éœ€è¦å¯¹å…¶è¿›è¡Œåˆ†¾l„。在UML中,提供äº?#8220;åŒ?Package)”来完成这一目标

  1.4、注释元�/p>

  ¾l“构事物是模型的主要构造块åQŒè¡Œä¸ÞZº‹ç‰©åˆ™æ˜¯è¡¥å……了模型中的动态部分,分组事物而是用来更好地组¾l‡æ¨¡åž‹ï¼Œä¼ég¹Žå·²ç»å¾ˆå®Œæ•´äº†ã€‚而注释事物则是用来锦上添èŠÞqš„åQŒå®ƒæ˜¯ç”¨æ¥åœ¨UML模型上添加适当的解释部åˆ?/p>

  2、关¾p?/p>

  UML模型的关¾pÀL¯”较多,下图

  

  2.1 兌™”关系

  兌™”(Association)表示两个¾cÖM¹‹é—´å­˜åœ¨æŸ¿Uè¯­ä¹‰ä¸Šçš„联¾p…R€‚关联关¾pÀLä¾›äº†é€šä¿¡çš„èµ\径,它是所有关¾pÖM¸­æœ€é€šç”¨ã€è¯­ä¹‰æœ€å¼Þqš„ã€?/p>

  在UML中,使用一条实¾U¿æ¥è¡¨ç¤ºå…Œ™”关系

  在关联关¾pÖM¸­åQŒæœ‰ä¸¤ç§æ¯”较ç‰ÒŽ®Šçš„å…³¾p»ï¼šèšåˆå’Œç»„å?/p>

  聚合关系åQšèšå?Aggregation)是一¿Uç‰¹ŒDŠåŞ式的兌™”。聚合表½Cºç±»ä¹‹é—´çš„å…³¾pÀL˜¯æ•´ä½“与部分的关系

  如果发现“部分”¾cȝš„存在åQŒæ˜¯å®Œå…¨ä¾èµ–äº?#8220;整体”¾cȝš„åQŒé‚£ä¹ˆå°±åº”该使用“¾l„合”关系来描˜q?/p>

  ¾l„合是聚合的变种åQŒåŠ å…¥äº†ä¸€äº›é‡è¦çš„è¯­ä¹‰ã€‚ä¹Ÿž®±æ˜¯è¯ß_¼Œåœ¨ä¸€ä¸ªç»„合关¾pÖM¸­ä¸€ä¸ªå¯¹è±¡ä¸€‹Æ¡å°±åªæ˜¯ä¸€ä¸ªç»„合的一部分åQ?#8220;整体”è´Ÿè´£“部分”的创建和破坏åQŒå½““整体”被破坏时åQ?#8220;部分”也随之消å¤?/p>

  聚合ž®±åƒæ±½èžRå’ŒèžR胎,汽èžR坏了胎还可以用。组合就像公司和下属部门åQŒå…¬å¸å€’闭了部门也ž®×ƒ¸å­˜åœ¨äº?

  2.2  泛化、实çŽîC¸Žä¾èµ–

  泛化关系描述了一般事物与该事物中的特ŒDŠç§¾cÖM¹‹é—´çš„关系åQŒä¹Ÿž®±æ˜¯çˆ¶ç±»ä¸Žå­¾cÖM¹‹é—´çš„关系ã€?/p>

  实现关系是用来规定接口和实现接口的类或组件之间的关系。接口是操作的集合,˜q™äº›æ“ä½œç”¨äºŽè§„定¾cÀLˆ–¾l„äšg的服务ã€?/p>

  有两个元素X、YåQŒå¦‚果修改元素X的定义可能会引è“v对另一个元素Y的定义的修改åQŒåˆ™¿U°å…ƒç´ Y依赖(Dependency)于元素Xã€?/p>

  二、规�/p>

  命名åQšä¹Ÿž®±æ˜¯ä¸ÞZº‹ç‰©ã€å…³¾pÕd’Œå›¾è“v名字。和ä»ÖM½•è¯­è¨€ä¸€æ øP¼Œåå­—都是一个标识符

  范围åQšä¸Ž¾cȝš„作用域相ä¼?

  可见性:PublicåQŒProtectedåQŒPrivateåQŒPackage

  三、UML公共机制

  1、规格描˜q?/p>

  在图形表½Cºæ³•的每个部分后面都有一个规格描˜q?ä¹Ÿç§°ä¸ø™¯¦˜q?åQŒå®ƒç”¨æ¥å¯ÒŽž„造块的语法和语义˜q›è¡Œæ–‡å­—叙述。这¿Uæž„思,也就使可视化视图和文字视囄¡š„分离 åQ?/p>

  2、UML修饰与通用划分

ã€€ã€€åœ¨äØ“äº†æ›´å¥½çš„è¡¨ç¤º˜q™äº›¾l†èŠ‚åQŒUMLä¸­è¿˜æä¾›äº†ä¸€äº›ä¿®é¥°ç¬¦åøP¼Œä¾‹å¦‚不同可视性的½W¦å·ã€ç”¨æ–œä½“字表½CºæŠ½è±¡ç±»

  UML通用划分åQ?/p>

  1)¾cÖM¸Žå¯¹è±¡çš„划分:¾cÀL˜¯ä¸€¿UæŠ½è±¡ï¼Œå¯¹è±¡æ˜¯ä¸€ä¸ªå…·ä½?的实ä¾?/p>

  2)接口与实现的分离åQšæŽ¥å£æ˜¯ä¸€¿Uå£°æ˜Žã€æ˜¯ä¸€ä¸ªå¥‘ ¾U¦ï¼Œä¹Ÿæ˜¯æœåŠ¡çš„å…¥å?实现则是负责实施接口提供 的契¾U?/p>

  3、UML扩展机制

  ˜q™éƒ¨åˆ†ä¸å®ÒŽ˜“描述åQŒå¾…æ”?邀月注 2009.2.18)

  构造型åQšåœ¨å®žé™…的徏模过½E‹ä¸­åQŒå¯èƒ½ä¼šéœ€è¦å®šä¹‰ä¸€äº›ç‰¹å®šäºŽæŸä¸ªé¢†åŸŸæˆ–某个系¾lŸçš„æž„造块

ã€€ã€€æ ‡è®°å€¼åˆ™æ˜¯ç”¨æ¥äØ“äº‹ç‰©æ·ÕdŠ æ–°ç‰¹æ€§çš„ã€‚æ ‡è®°å€¼çš„è¡¨ç¤ºæ–ÒŽ³•是用形如“{标记信息}”的字½W¦ä¸²

  ¾U¦æŸæ˜¯ç”¨æ¥å¢žåŠ æ–°çš„è¯­ä¹‰æˆ–æ”¹å˜å·²å­˜åœ¨è§„åˆ™çš„ä¸€¿Uæœºåˆ?自由文本和OCL两种表示æ³?。约束的表示法和标记值法¾cÖM¼¼åQŒéƒ½æ˜¯ä‹É用花括号括è“v来的串来表示åQŒä¸˜q‡å®ƒæ˜¯ä¸èƒ½å¤Ÿæ”‘Öœ¨å…ƒç´ ä¸­çš„åQŒè€Œæ˜¯æ”‘Öœ¨ç›¸å…³çš„元素附˜q‘ã€?/p>

  4、UML视图和图

  

  囑֐ã€€ã€€ã€€ã€€ã€€ã€€ã€€ã€€ã€€ã€€ã€€ã€€åŠŸèƒ½ã€€ã€€ã€€ã€€ã€€ã€€ã€€ã€€ã€€ã€€ã€€ã€€ã€€ã€€ã€€ã€€å¤‡æ³¨

  ¾cÕd›¾ã€€ã€€ã€€ã€€ã€€ã€€æè¿°¾c…R€ç±»çš„特性以及类之间的关¾p…R€€ã€€ã€€ã€€ã€€ã€€ã€€ã€€UML 1原有

  对象图     描述一个时间点上系¾lŸä¸­å„个对象的一个快ç…?   UML 1非正式图

  复合¾l“构图   描述¾cȝš„˜qè¡Œæ—¶åˆ»çš„分解             UML 2.0新增

  构äšg图     描述构äšg的结构与˜qžæŽ¥ã€€ã€€ã€€ã€€ã€€ã€€ã€€ã€€ã€€ã€€ã€€ã€€ã€€ã€€UML 1原有

  部çÖv图     描述在各个节点上的部¾|ŒÓ€€ã€€ã€€ã€€ã€€ã€€ã€€ã€€ã€€ã€€ã€€ã€€ã€€UML 1原有

  包图      描述¾~–译时的层次¾l“构              UML中非正式å›?/p>

  用例图     描述用户与系¾lŸå¦‚何交互             UML 1原有

  ‹zÕdŠ¨å›¾ã€€ã€€ã€€ã€€ã€€æè¿°˜q‡ç¨‹è¡ŒäØ“ä¸ŽåÆˆè¡Œè¡Œä¸ºã€€ã€€ã€€ã€€ã€€ã€€ã€€ã€€ã€€ã€€ã€€ã€€ã€€UML 1原有

  状态机图    描述事äšg如何改变对象生命周期          UML 1原有

  ™åºåºå›¾ã€€ã€€ã€€ã€€ã€€æè¿°å¯¹è±¡ä¹‹é—´çš„交互,重点在强调顺序       UML 1原有

  通信图     描述对象之间的交互,重点在于˜qžæŽ¥ã€€ã€€ã€€ã€€ã€€ã€€ã€€ã€€UML 1中的协作å›?/p>

  定时图     描述对象之间的交互,重点在于定时        UML 2.0 新增

  交互概观图   是一¿Ué¡ºåºå›¾ä¸Žæ´»åŠ¨å›¾çš„æØœåˆã€€ã€€ã€€ã€€ã€€ã€€ã€€ã€€ã€€ã€€ã€€UML 2.0新增

  附:开发过½E‹ä¸Žå›„¡š„对应关系

  





]]>
UML手册http://www.aygfsteel.com/hulizhong/archive/2009/03/10/258873.html二胡二胡Tue, 10 Mar 2009 10:08:00 GMThttp://www.aygfsteel.com/hulizhong/archive/2009/03/10/258873.htmlhttp://www.aygfsteel.com/hulizhong/comments/258873.htmlhttp://www.aygfsteel.com/hulizhong/archive/2009/03/10/258873.html#Feedback0http://www.aygfsteel.com/hulizhong/comments/commentRss/258873.htmlhttp://www.aygfsteel.com/hulizhong/services/trackbacks/258873.html

目录  åQ?br />


UML视图和图



一  åQšé™æ€è§†å›?

静态视å›?的主要组成部分是 ¾cÕd’Œå…³ç³» åQŒå®ƒæ˜„¡¤ºä¸ºç±»å›?å› äØ“å®ƒä¸æè¿°æ—‰™—´ç›¸å…³çš„行为,因而是静态的åQ?关系包括 åQšå…³è”,¾l§æ‰¿ 和各¿Uä¾èµ–,依赖包括实现和ä‹É用。类间的关系¾l˜æˆ˜qžæŽ¥¾cȝš„路径åQŒä¸åŒç§¾cȝš„关系ç”Þqº¿ä¸Šçš„¾l“构和èµ\å¾?或端点上的修饰来区分ã€?br />
例子 åQ?br />
¼œ¨æˆ¿åº”用的类å›?br />



图例 åQ?br />

äº?åQšç”¨ä¾‹å›¾

ç”¨ä¾‹ä½œäØ“äº¤äº’è§†å›¾ä¸­çš„åä½œæ¥å®žçŽ°çš„ã€?主要从活动者的角度考虑ã€?br />


ä¸?åQ?交互视图

1 åQšé¡ºåºå›¾



2 åQšåä½œå›¾




å›?åQšçŠ¶æ€æœºè§†å›¾

状态机昄¡¤ºä¸ºçŠ¶æ€å›¾



äº?åQšæ´»åŠ¨è§†å›?br />
横条表示控制的分叉河˜qžæŽ¥



å…?åQšç‰©ç†è§†å›?

有两¿Uç‰©ç†è§†å›?åQšå®žçŽ°è§†å›?å’?配置视图

1 åQšå®žçŽ°è§†å›?

实现视图昄¡¤ºä¸ºæž„件图

接口昄¡¤ºä¸ºå…·æœ‰å“¦åç§°çš„圆åQŒå³ç›¸å…³çš„æœåС集 åQŒè¿žæŽ¥æž„件和接口的实¾U¿è¡¨½Cºæž„件提供接口所列ä‹D的服务。从构äšgè‡ÏxŽ¥å£çš„è™šçº¿è¡¨æ˜Žæž„äšg需要接口所提供的服åŠ?br />



2 åQšé…¾|®è§†å›?

配置视图表达了运行时æ–?æž„äšg实力在结点实例中的分布,¾l“点是运行资源,如计½Ž—机åQŒè®¾å¤‡æˆ–内存åQŒè¯¥è§†å›¾å…è®¸åˆ†å¸ƒå¼çš„¾l“果和资源分配被评估åQŒä¸‹é¢å›¾ä¸­å±•½CÞZº†¾pȝ»Ÿä¸­ç»“点的¿Uç±»å’Œç»“ç‚ÒŽ‰€æ‹¥æœ‰æž„äšg的种¾c»ï¼ŒèŠ‚ç”µæ˜„¡¤ºä¸ºæ–¹å—ã€?br />


下图 æ˜?一个实例çñ”别的配置å›?



ä¸?åQšæ¨¡åž‹ç®¡ç†è§†å›?



最�来几张图






]]>
UML å›?ä¹?一 åQ?¾cÕd›¾http://www.aygfsteel.com/hulizhong/archive/2009/03/10/258872.html二胡二胡Tue, 10 Mar 2009 10:06:00 GMThttp://www.aygfsteel.com/hulizhong/archive/2009/03/10/258872.htmlhttp://www.aygfsteel.com/hulizhong/comments/258872.htmlhttp://www.aygfsteel.com/hulizhong/archive/2009/03/10/258872.html#Feedback0http://www.aygfsteel.com/hulizhong/comments/commentRss/258872.htmlhttp://www.aygfsteel.com/hulizhong/services/trackbacks/258872.html




¾cÕd›¾ä¸­çš„关系 åQ?br />
1 åQšä¸€èˆ¬åŒ–åQˆGeneralization åQ‰å…³¾p?



2 åQšå…³è? Association )关系



               2.1 :  聚合åQˆAggregation )关系
                                 

               2.2 : 合成(Composition)关系
                                 

3 :  依赖 ( Dependency )关系
                               



]]>
¾cÖM¸Ž¾cÕd…³¾pȝš„UML图与代码表现http://www.aygfsteel.com/hulizhong/archive/2009/03/10/258871.html二胡二胡Tue, 10 Mar 2009 09:55:00 GMThttp://www.aygfsteel.com/hulizhong/archive/2009/03/10/258871.htmlhttp://www.aygfsteel.com/hulizhong/comments/258871.htmlhttp://www.aygfsteel.com/hulizhong/archive/2009/03/10/258871.html#Feedback0http://www.aygfsteel.com/hulizhong/comments/commentRss/258871.htmlhttp://www.aygfsteel.com/hulizhong/services/trackbacks/258871.html è½?http://www.aygfsteel.com/liuwentao253/archive/2008/08/01/219416.html
一  åQ?


äº?åQ?





ä¸?åQ?



å›?åQ?br />


äº?åQ?




¾cÖM¸Ž¾cÖM¹‹é—´çš„关系对于理解面向对象å…ähœ‰å¾ˆé‡è¦çš„作用åQŒå­˜åœ¨ä»¥ä¸‹å…³¾p?
(1)泛化(Generalization)   åQšç‹—与动ç‰?nbsp; (½Iºç®­å¤?
(2)å…Œ™”(Association)       åQšå…¬åæ€¸Žå‘˜å·¥æœ‰ç‰¹å®šçš„æŸç§å…³ç³» (实线)
(3)依赖(Dependency)    åQšäh依赖èžÞZ¸åˆ€ (虚线½Ž­å¤´)
(4)聚合(Aggregation)     åQ?电脑和CPUåQŒä¸»æ?(菱åÅž½Iºé—´å¤?







详细展开  åQ?
一 .泛化(Generalization)
 è¡¨ç¤º¾cÖM¸Ž¾cÖM¹‹é—´çš„¾l§æ‰¿å…³ç³»åQ?strong>接口与接口之间的¾l§æ‰¿å…³ç³»
åQ?u>或类å¯ÒŽŽ¥å£çš„实现关系ã€?br />  ä¸€èˆ¬æ³›åŒ–的关系是从子类指向父类的:
 çˆ¶ç±» 父类实例åQnew 子类()




1/**
2* ä¸€ä¸ªæµ‹è¯•ç±»
3*/

4public class Demo{    
5    public void test() {
6        //老虎的实ä¾?nbsp;也属于动物类åž?nbsp;
7        Animal animal = new Tiger();  
8    }
    
9}
 



1/**
2*  åŠ¨ç‰©¾c?br /> 3*/

4public class Animal{
5
6}
    


1/**
2* è€è™Ž¾c?nbsp;
3*/

4public class Tiger extends Animal{
5
6}
  


�.依赖(Dependency)

对于两个相对独立的对象,当一个对象(èžÞZ¸åˆ€åQ‰è´Ÿè´£æž„造另一个对è±?äº?的实例,或者一个对è±?äº?依赖另一个对象(èžÞZ¸åˆ€åQ‰çš„æœåŠ¡æ—Óž¼Œ˜q™ä¸¤ä¸ªå¯¹è±¡ä¹‹é—´ä¸»è¦ä½“çŽîCؓ依赖关系ã€?br />
下面˜q™ä¸ªä¾‹å­æ˜„¡„¶å±žäºŽåŽè€?åQšäh要做一个拧èžÞZ¸çš„动作,他就要依赖于 èžÞZ¸åˆ€å¯¹è±¡åQŒå› ä¸ºåªæœ‰èžºä¸åˆ€å¯¹è±¡æ‰æä¾›æ‹§èžÞZ¸çš„æœåŠ¡ã€?



 1/**
 2 * è¯´æ˜Ž åQšäh ˜q™ä¸ª ¾c?nbsp;
 3 */

 4public class Person {
 5    /**
 6     * äººæ‹¥æœ‰çš„一ä¸?nbsp; æ‹§èžºä¸?nbsp; çš?nbsp; åŠ¨ä½œ ä¾èµ–于螺丝刀˜q™ä¸ª¾c?br />  7     * @param screwdriver åQšèžºä¸åˆ€¾c?br />  8     */

 9     public void screw(Screwdriver screwdriver)
10        //èžÞZ¸åˆ€¾cÀLä¾›äº†æ‹§èžºä¸è¿™ä¸ªæœåŠ?/span>
11        screwdriver.screw();    
12    }
  
13}


ä¸?.å…Œ™”(Association)
对于两个相对独立的对象,当一个对象的实例与另一个对象的一些特定实例存在固定的对应关系æ—Óž¼Œ˜q™ä¸¤ä¸ªå¯¹è±¡ä¹‹é—´äؓ兌™”关系ã€?br /> å…Œ™”关系是ä‹É用实例变量来实现
æ¯”å¦‚å®¢æˆ·å’Œè®¢å•ï¼Œæ¯ä¸ªè®¢å•å¯¹åº”ç‰¹å®šçš„å®¢æˆøP¼Œæ¯ä¸ªå®¢æˆ·å¯¹åº”一些特定的订单åQ›å†ä¾‹å¦‚公司和员工,每个公司对应一些特定的员工åQŒæ¯ä¸ªå‘˜å·¥å¯¹åº”一特定的公å?br />



 1/**
 2 * å…¬å¸
 3 */

 4public class Company{   
 5    //员工
 6    private Employee employee;
 7
 8    /**
 9     * å…¬å¸˜qä½œ
10      */

11    public void run(){    
12        employee.startWorking();    
13    }

14    
15    public Employee getEmployee(){    
16        return employee;    
17    }
    
18    public void setEmployee(Employee employee){    
19        this.employee=employee;    
20    }
  
21}
 

å›?åQ?聚合åQˆAggregationåQ?br /> 当对象A被加入到对象Bä¸­ï¼ŒæˆäØ“å¯¹è±¡B的组成部分时åQŒå¯¹è±¡B和对象A之间䏸™šé›†å…³¾p…R€‚聚合是兌™”关系的一¿Uï¼Œæ˜¯è¾ƒå¼ºçš„å…Œ™”关系åQŒå¼ºè°ƒçš„æ˜¯æ•´ä½“与部分之间的关¾p…R€?br /> [å…Œ™”与聚合的区别]
(1)å…Œ™”关系所涉及的两个对象是处在同一个层‹Æ¡ä¸Šçš„。比如äh和自行èžRž®±æ˜¯ä¸€¿Uå…³è”å…³¾p»ï¼Œè€Œä¸æ˜¯èšåˆå…³¾p»ï¼Œå› äØ“äºÞZ¸æ˜¯ç”±è‡ªè¡Œè½¦ç»„成的ã€?br /> 聚合关系涉及的两个对象处于不òq³ç­‰çš„层‹Æ¡ä¸ŠåQŒä¸€ä¸ªä»£è¡¨æ•´ä½“,一个代表部分。比如电脑和它的昄¡¤ºå™¨ã€é”®ç›˜ã€ä¸»æ¿ä»¥åŠå†…存就是聚集关¾p»ï¼Œå› äØ“ä¸ÀL¿æ˜¯ç”µè„‘çš„¾l„成部分ã€?br /> (2)对于å…ähœ‰èšé›†å…³ç³»åQˆå°¤å…¶æ˜¯å¼ø™šé›†å…³¾p»ï¼‰çš„两个对象,整体对象会制¾U¦å®ƒçš„组成对象的生命周期。部分类的对象不能单独存在,它的生命周期依赖于整体类的对象的生命周期åQŒå½“整体消失åQŒéƒ¨åˆ†ä¹Ÿž®±éšä¹‹æ¶ˆå¤±ã€‚比如张三的电脑被偷了,那么电脑的所有组件也不存在了åQŒé™¤éžå¼ ä¸‰äº‹å…ˆæŠŠä¸€äº›ç”µè„‘çš„¾l„äšgåQˆæ¯”如硬盘和内存åQ‰æ‹†äº†ä¸‹æ¥ã€?br />


 1public class Computer{    
 2    private CPU cpu;    
 3    public CPU getCPU(){    
 4        return cpu;    
 5    }
    
 6    public void setCPU(CPU cpu){    
 7        this.cpu=cpu;    
 8    }
    
 9    //开启电è„?nbsp;   
10    public void start(){    
11        //cpu˜qä½œ    
12        cpu.run();    
13    }
    
14}
  


]]>用例建模技å·?/title><link>http://www.aygfsteel.com/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.aygfsteel.com/hulizhong/archive/2009/03/10/258866.html</guid><wfw:comment>http://www.aygfsteel.com/hulizhong/comments/258866.html</wfw:comment><comments>http://www.aygfsteel.com/hulizhong/archive/2009/03/10/258866.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/hulizhong/comments/commentRss/258866.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/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="http://www.ibm.com/i/c.gif" width="8" height="1" alt="" /></td><td width="16"><img alt="ž®†æ‰“印机的版面设¾|®æˆæ¨ªå‘打印模式" height="16" 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>'); //--> </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="本文介绍了一些提高系¾lŸç”¨ä¾‹æ¨¡åž‹è´¨é‡çš„æŠ€å·§å’ŒæŠ€æœ¯ã€‚本文改¾~–自 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="http://www.ibm.com/i/c.gif" width="8" height="1" alt="" /></td><td width="16"><img src="http://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>¾U§åˆ«åQ?初çñ”</p> <p><a >Scott W. Ambler</a> (<a href="mailto:scott.ambler@ronin-intl.com?subject=%E7%94%A8%E4%BE%8B%E5%BB%BA%E6%A8%A1%E6%8A%80%E5%B7%A7&amp;cc=scott.ambler@ronin-intl.com">scott.ambler@ronin-intl.com</a>), 总裁, Ronin International<br /> </p> <p>2001 òq?1 æœ?04 æ—?/p> <blockquote>本文介绍了一些提高系¾lŸç”¨ä¾‹æ¨¡åž‹è´¨é‡çš„æŠ€å·§å’ŒæŠ€æœ¯ã€‚本文改¾~–自 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>从参与者的角度òq¶ä»¥ä¸ÕdŠ¨è¯­æ€ç¼–å†™ç”¨ä¾‹ã€?/strong> <br /> 应该以主动语态:“学生表明参加研习班意å?#8221;åQŒè€Œä¸æ˜¯è¢«åŠ¨è¯­æ€?#8220;研习班意向被学生表明”来编写用例。而且åQŒåº”该从参与者的角度来编写用例。毕竟,用例的目的是理解用户如何对系¾lŸè¿›è¡Œæ“ä½œã€?</p> <p><strong>¾~–写æ–ÒŽ¡ˆæ–‡æœ¬åQŒè€ŒéžåŠŸèƒ½éœ€æ±‚ã€?/strong> <br /> 用例描述的是对参与者来说有价值的一¾pÕdˆ—行动åQŒè€Œä¸æ˜¯ç‰¹æ€§é›†ã€‚例如,“招收研习班的学生”用例描述的是学生如何与系¾lŸäº¤äº’来参加研习班。它没有描述用户界面看上åŽÀL˜¯ä»€ä¹ˆæ ·å­ï¼Œæˆ–者它是如何工作的。有一些其它的模型来描˜q°è¿™äº›é‡è¦çš„信息åQŒä¾‹å¦‚用æˆïL•Œé¢æ¨¡åž‹å’Œå¢žè¡¥è§„范。面向对象分析非常复杂,因此需要对它ä‹É用几¿Uæ¨¡åž‹ï¼Œòq¶ä¸”应该适当地应用每一¿Uæ¨¡åž‹ã€?</p> <p><strong>用例只记载行为需求ã€?/strong> <br /> 用例既不是类规范åQŒä¹Ÿä¸æ˜¯æ•°æ®è§„范。这是应该由概念性模型捕捉的一¿Uä¿¡æ¯ï¼Œåœ¨å¯¹è±¡ä¸–界中åQŒå®ƒæ˜¯é€šè¿‡ UML¾cÀL¨¡åž‹å¾æ¨¡çš„。您往往会引用概忉|€§æ¨¡åž‹ä¸­æè¿°çš„ç±»åQŒä¾‹å¦‚,“参加研习ç?#8221;用例包括äº?#8220;研习ç?#8221;å’?#8220;学生”½{‰æ¦‚念,它们都将由概忉|€§æ¨¡åž‹æ˜q°ã€?</p> <p><strong>不要忘记用户界面ã€?/strong> <br /> ¾pȝ»Ÿç”¨ä¾‹¾lå¸¸å¼•用ä¸È”¨æˆïL•Œé?(UI)元素åQŒè¿™äº›å…ƒç´ å¸¸å¸¸ç§°ä¸?#8220;边界”æˆ?#8220;用户界面”™å¹ï¼Œä¾‹å¦‚ HTML™åµé¢å’ŒæŠ¥è¡¨ã€‚用例有时也引用一些次要的 UI元素åQŒä¾‹å¦‚按钮或数据输入字段åQŒä½†˜q™ç§¾U§åˆ«çš„ç»†èŠ‚åÆˆä¸å¤ªå¸¸è§ã€?</p> <p><strong>创徏用例模板ã€?/strong> <br /> 用例包含了相当数量的信息åQŒè¿™äº›ä¿¡æ¯å¯ä»¥è½»æ˜“地以常见格式记载。您应该考虑开发自å·Þqš„æ¨¡æ¿åQˆè¯·å‚阅技å·?#8220; <a >记蝲用例</a>”åQ‰ã€?</p> <p><strong>始终如一地组¾l‡ç”¨ä¾‹å›¾ã€?/strong> <br /> 一般的做法是垂直地¾l˜åˆ¶¾l§æ‰¿ (inheritance) 和扩å±?(extend)å…Œ™”åQŒåœ¨çˆÓž¼åŸºæœ¬ç”¨ä¾‹ä¸‹é¢¾l˜åˆ¶¾l§æ‰¿åQæ‰©å±•ç”¨ä¾‹ã€‚åŒæ øP¼Œé€šå¸¸æ°´åã^¾l˜åˆ¶åŒ…含(include) å…Œ™”。请注意åQŒè¿™äº›æ˜¯½Ž€å•çš„¾léªŒæ³•则 --只要始终遵åó@˜q™äº›æ³•则åQŒäñ”生的囑ְ†å¾ˆå®¹æ˜“理解ã€?</p> <p><strong>不要忘记¾pȝ»Ÿå¯¹å‚与者行动的响应ã€?/strong> <br /> 用例既应该描˜q°å‚与者是如何与系¾lŸäº¤äº’çš„åQŒä¹Ÿåº”该描述¾pȝ»Ÿå¦‚何响应˜q™äº›äº¤äº’。例如,åœ?#8220;参加研习ç?#8221;用例中,如果¾pȝ»Ÿåœ¨å­¦ç”Ÿè¡¨æ˜Žä»–们希望参加研习班时没有做出响应,学生ž®×ƒ¼šå¾ˆæ²®ä¸§åœ°¼›Õd¼€ã€?</p> <p><strong>备选行动过½E‹éžå¸”R‡è¦ã€?/strong> <br /> 如果一切顺利,使用的将是基本行动过½E?--但也不要忘记备选过½E‹ã€‚引入备选过½E‹æ˜¯ä¸ÞZº†æè¿°æ½œåœ¨çš„ä‹É用错误以及商业逻辑错误和异常。这些重要的信息对于驱动¾pȝ»Ÿçš„设计来说很有必要,因此不要忘记在用例中对它们徏模ã€?</p> <p><strong>不要è¢?<<include>> å’?<<extend>>å…Œ™”所困扰ã€?/strong> <br /> 我不是很¼‹®å®šåˆ°åº•发生了什么事åQŒä½†æˆ‘æ€ÀL˜¯åœ¨æƒ³åŒ…含 (include) 和扩å±?extend) å…Œ™”åQŒä»¥åŠæ—§ç‰ˆæœ¬ UML 中ä‹Éç”?(uses) 和扩å±?(extends)å…Œ™”的正¼‹®ä‹É用从来没有得到很好的描述。结果,用例建模ž®ç»„往往在这些关联的正确应用上争è®ÞZ¸ä¼‘,在整个徏模技术中一些有­‘£ä½†‹Æ¡è¦çš„部分上‹¹ªè´¹äº†æƒŠäººçš„æ—‰™—´ã€‚我曑֜¨ä¸€ä¸ªç»„¾l‡ä¸­å·¥ä½œåQŒè¿™å®¶ç»„¾l‡å±…然取¾~”了<<include>> å’?<<extend>>原型的ä‹É用,几个星期后,当意识到公司仍然需要这些概忉|—¶ä¸å¾—不撤消了˜q™ç§æžç«¯çš„è§£å†Ïx–¹æ¡ˆï¼Œè€Œè¿™æ—¶è¯¥¾l„织对它们的正确使用˜q˜æ²¡æœ‰è¾¾æˆå…±è¯†ã€?</p> <p><strong>让用例带动用æˆäh–‡æ¡£ã€?/strong> <br /> 用户文档的目的是描述如何使用¾pȝ»Ÿã€‚每个用例都描述了参与者通过使用¾pȝ»Ÿæ‰€é‡‡å–的一¾pÕdˆ—动作。简而言之,用例包含从中开始编写问党用æˆïL¨³å½“的信息。例如,可以使用“参加研习ç?#8221;ç”¨ä¾‹ä½œäØ“åŸºç¡€æ¥ç¼–å†™ç³»¾lŸç”¨æˆäh–‡æ¡£çš„“如何参加研习ç?#8221;一节ã€?</p> <p><strong>让用例带动演½Cºã€?/strong> <br /> 软äšg开发过½E‹ä¸­çš„一部分是向™å¹ç›®èµ„金½Ž¡ç†è€…通报工作成果åQŒå› æ­¤æœ‰æ—‰™œ€è¦æä¾›æ¼”½Cºã€‚因为用例是从用æˆïLš„角度¾~–写的,它们包含了演½CÞZ¸­å¯¹èµ„金管理者可能希望听到的事物的有价值的深刻见解。换句话è¯ß_¼Œç”¨ä¾‹é€šå¸¸åŒ…含制定演示½E¿æ‰€éœ€çš„逻辑ã€?</p> <br /> <br /> <p><a name="resources"><span id="wmqeeuq" class="atitle">参考资æ–?</span></a></p> <ul> <li>您可以参阅本文在 developerWorks 全球站点上的 <a >英文原文</a>. <br /> <br /> </li> <li><a ><em>The Object Primer 2nd Edition</em> </a>åQŒç”± Scott W. Ambler 著。New York: Cambridge University Press, 2001ã€?<br /> <br /> </li> <li><a ><em>The Unified Process Inception Phase</em> </a>åQŒç”± Scott W. Ambler å’?Larry L. Constantine 合著。Gilroy, CA: R&D Books, 2000ã€?<br /> <br /> </li> <li><a ><em>Software For Use: A Practical Guide to the Models and Methods of Usage-Centered Design</em> </a>åQŒç”± Larry L. Constantine and Lucy A.D. Lockwood 合著ã€?<br /> <br /> </li> <li><a ><em>The Unified Modeling Language Reference Manual</em> </a>åQŒç”± James Rumbaugh、Grady Booch å’?Ivar Jacobson 合著。Reading, MA: Addison-Wesley Longman, Inc., 1999ã€?<br /> </li> </ul> <br /> <br /> <p><a name="author"><span id="wmqeeuq" 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 >Ronin International</a> 的总裁åQŒè¯¥å…¬å¸æ˜¯ä¸€å®¶ä¸“门提供面向对象èÊY件过½E‹æŒ‡å¯¹{€ä½“¾pȝ»“构徏模和 Enterprise JavaBean (EJB) 开发的咨询企业。他创作或者与其他人合著了几本有关面向对象开发的书籍åQŒåŒ…括最˜q‘出版的 <em>Object Primer 2nd Edition</em>åQŒè¯¥ä¹¦è¯¦¾l†ä»‹¾läº†æœ¬æ–‡æ‰€æ¦‚述的主题。可以通过 <a href="mailto:scott.ambler@ronin-intl.com?cc=scott.ambler@ronin-intl.com">scott.ambler@ronin-intl.com</a> 与他联系åQŒä»–的网站位äº?<a >www.ambysoft.com</a>ã€?</p> </td> </tr> </tbody> </table> <br /> </td> </tr> </tbody> </table><img src ="http://www.aygfsteel.com/hulizhong/aggbug/258866.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/hulizhong/" target="_blank">二胡</a> 2009-03-10 17:36 <a href="http://www.aygfsteel.com/hulizhong/archive/2009/03/10/258866.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用例建模指南http://www.aygfsteel.com/hulizhong/archive/2009/03/10/258766.html二胡二胡Tue, 10 Mar 2009 04:04:00 GMThttp://www.aygfsteel.com/hulizhong/archive/2009/03/10/258766.htmlhttp://www.aygfsteel.com/hulizhong/comments/258766.htmlhttp://www.aygfsteel.com/hulizhong/archive/2009/03/10/258766.html#Feedback0http://www.aygfsteel.com/hulizhong/comments/commentRss/258766.htmlhttp://www.aygfsteel.com/hulizhong/services/trackbacks/258766.html

用例建模指南

developerWorks
文档选项
ž®†æ‰“印机的版面设¾|®æˆæ¨ªå‘打印模式

打印本页

ž®†æ­¤™åµä½œä¸ºç”µå­é‚®ä»¶å‘é€? src=

ž®†æ­¤™åµä½œä¸ºç”µå­é‚®ä»¶å‘é€?/strong>


¾U§åˆ«åQ?初çñ”

傅纯一, Rational中国区技术销售经ç? IBM中国有限公司软äšgéƒ?br />

2004 òq?11 æœ?01 æ—?/p>

用例(Use Case)是一¿Uæ˜q°ç³»¾lŸéœ€æ±‚çš„æ–ÒŽ³•åQŒä‹É用用例的æ–ÒŽ³•来描˜q°ç³»¾lŸéœ€æ±‚çš„˜q‡ç¨‹ž®±æ˜¯ç”¨ä¾‹å»ºæ¨¡ã€‚用例方法最早是由Iva Jackboson博士提出的,后来被综合到UML规范之中åQŒæˆä¸ÞZ¸€¿Uæ ‡å‡†åŒ–的需求表˜qîC½“¾p…R€‚用例的使用在RUP中被推崇备至åQŒæ•´ä¸ªRUP‹¹ç¨‹éƒ½è¢«¿UîC½œæ˜?用例驱动"(Use-Case Driven)的,各种¾cÕdž‹çš„开发活动包括项目管理、分析设计、测试、实现等都是以系¾lŸç”¨ä¾‹äؓ主要输入工äšgåQŒç”¨ä¾‹æ¨¡åž‹å¥ å®šäº†æ•´ä¸ª¾pȝ»Ÿè½¯äšg开发的基础ã€?/blockquote>

1. 什么是用例åQ?/span>

在介始用例方法之前,我们首先来看一下传¾lŸçš„需求表˜q°æ–¹å¼?"软äšg需求规¾U?(Software Requirement Specification)。传¾lŸçš„软äšg需求规¾U¦åŸºæœ¬ä¸Šé‡‡ç”¨çš„æ˜¯åŠŸèƒ½åˆ†è§£çš„æ–¹å¼æ¥æè¿°¾pȝ»ŸåŠŸèƒ½åQŒåœ¨˜q™ç§è¡¨è¿°æ–¹å¼ä¸­ï¼Œ¾pȝ»ŸåŠŸèƒ½è¢«åˆ†è§£åˆ°å„ä¸ª¾pȝ»ŸåŠŸèƒ½æ¨¡å—ä¸­ï¼Œæˆ‘ä»¬é€šè¿‡æè¿°¾l†åˆ†çš„ç³»¾lŸæ¨¡å—的功能来达到描˜q°æ•´ä¸ªç³»¾lŸåŠŸèƒ½çš„ç›®çš„ã€‚ä¸€ä¸ªå…¸åž‹çš„è½¯äšg需求规¾U¦å¯èƒ½å…·æœ‰ä»¥ä¸‹åŞ式:



采用˜q™ç§æ–ÒŽ³•来描˜q°ç³»¾lŸéœ€æ±‚,非常å®ÒŽ˜“æ·äh·†éœ€æ±‚和设计的界限,˜q™æ ·çš„表˜q°å®žé™…上已经包含了部分的设计在内。由此常常导致这æ ïLš„˜qähƒ‘åQšç³»¾lŸéœ€æ±‚应该详¾l†åˆ°ä½•种½E‹åº¦åQŸä¸€ä¸ªæžç«¯å°±æ˜¯éœ€æ±‚可以详¾l†åˆ°æ¦‚要设计åQŒå› ä¸ø™¿™æ ïLš„需求表˜q°æ—¢åŒ…含了外部需求也包含了内部设计。在有些公司的开发流½E‹ä¸­åQŒè¿™¿Uéœ€æ±‚被¿UîCØ“"内部需æ±?åQŒè€Œå¯¹åº”äºŽç”¨æˆ·çš„åŽŸå§‹è¦æ±‚åˆ™è¢«ç§°ä¹‹äØ“"外部需æ±?ã€?/p>

功能分解æ–ÒŽ³•的另一个缺ç‚ÒŽ˜¯˜q™ç§æ–ÒŽ³•分割了各™å¹ç³»¾lŸåŠŸèƒ½çš„åº”ç”¨çŽ¯å¢ƒåQŒä»Žå„项功能™å¹å…¥æ‰‹ï¼Œä½ å¾ˆéš¾äº†è§£åˆ°˜q™äº›åŠŸèƒ½™åÒŽ˜¯å¦‚ä½•ç›æ€º’å…Œ™”来实çŽîC¸€ä¸ªå®Œæˆçš„¾pȝ»ŸæœåŠ¡çš„ã€‚æ‰€ä»¥åœ¨ä¼ ç»Ÿçš„SRS文档中,我们往往需要另外一些章节来描述¾pȝ»Ÿçš„æ•´ä½“ç»“æž„åŠå„éƒ¨åˆ†ä¹‹é—´çš„ç›æ€º’å…Œ™”åQŒè¿™äº›å†…容ä‹Éå¾—SRS需求更象是一个设计文档ã€?/p>

1.1 参与者和用例

从用æˆïLš„角度来看åQŒä»–ä»¬åÆˆä¸æƒ³äº†è§£¾pȝ»Ÿçš„内部结构和设计åQŒä»–们所兛_¿ƒçš„æ˜¯¾pȝ»Ÿæ‰€èƒ½æä¾›çš„æœåŠ¡åQŒä¹Ÿž®±æ˜¯è¢«å¼€å‘出来的¾pȝ»Ÿž®†æ˜¯å¦‚何被ä‹É用的åQŒè¿™ž®Þq”¨ä¾‹æ–¹æ³•的基本思想。用例模型主要由以下模型元素构成åQ?/p>

  • 参与è€?Actor)
    参与者是指存在于被定义系¾lŸå¤–éƒ¨åÆˆä¸Žè¯¥¾pȝ»Ÿå‘生交互的äh或其他系¾lŸï¼Œä»–们代表的是¾pȝ»Ÿçš„ä‹É用者或使用环境ã€?
  • 用例(Use Case)
    用例用于表示¾pȝ»Ÿæ‰€æä¾›çš„æœåŠ¡ï¼Œå®ƒå®šä¹‰äº†¾pȝ»Ÿæ˜¯å¦‚何被参与者所使用的,它描˜q°çš„æ˜¯å‚ä¸Žè€…äØ“äº†ä‹É用系¾lŸæ‰€æä¾›çš„æŸä¸€å®Œæ•´åŠŸèƒ½è€Œä¸Ž¾pȝ»Ÿä¹‹é—´å‘生的一ŒDµå¯¹è¯ã€?
  • 通讯兌™”(Communication Association)
    通讯兌™”用于表示参与者和用例之间的对应关¾p»ï¼Œå®ƒè¡¨½Cºå‚与者ä‹É用了¾pȝ»Ÿä¸­çš„哪些服务åQˆç”¨ä¾‹ï¼‰åQŒæˆ–者说¾pȝ»Ÿæ‰€æä¾›çš„æœåŠ¡ï¼ˆç”¨ä¾‹åQ‰æ˜¯è¢«å“ªäº›å‚与者所使用的ã€?

˜q™å¤§ä¸‰ç§æ¨¡åž‹å…ƒç´ åœ¨UML中的表述如下图所½Cºã€?/p>

以银行自动提‹Æ¾æœº(ATM)ä¸ÞZ¾‹åQŒå®ƒçš„主要功能可以由下面的用例图来表½Cºã€‚ATM的主要ä‹É用者是银行客户åQŒå®¢æˆ·ä¸»è¦ä‹É用自动提‹Æ¾æœºæ¥è¿›è¡Œé“¶è¡Œå¸æˆïLš„æŸ¥è¯¢ã€æ‹Æ‘Ö’Œè½¬å¸äº¤æ˜“ã€?/p>

通讯兌™”表示的是参与者和用例之间的关¾p»ï¼Œ½Ž­å¤´è¡¨ç¤ºåœ¨è¿™ä¸€å…³ç³»ä¸­å“ªä¸€æ–ÒŽ˜¯å¯¹è¯çš„主动发赯‚€…,½Ž­å¤´æ‰€æŒ‡æ–¹æ˜¯å¯¹è¯çš„被动接受者;如果你不惛_¼ºè°ƒå¯¹è¯ä¸­çš„主动与被动关系åQŒå¯ä»¥ä‹É用不带箭头的兌™”实线。在参与者和用例之间的信息流不是由通讯兌™”来表½Cºçš„åQŒè¯¥ä¿¡æ¯‹¹æ˜¯¾~ºçœå­˜åœ¨çš„(用例本èín描述的就是参与者和¾pȝ»Ÿä¹‹é—´çš„对话)åQŒåƈ且信息流向是双向的,它与通讯兌™”½Ž­å¤´æ‰€æŒ‡çš„æ–¹å‘äºÏx— å…³ç³»ã€?/p>

1.2 用例的内�/span>

用例图ä‹É我们对系¾lŸçš„功能有了一个整体的认知åQŒæˆ‘们可以知道有哪些参与者会与系¾lŸå‘生交互,每一个参与者需要系¾lŸäؓ它提供什么样的服务。用例描˜q°çš„æ˜¯å‚与者与¾pȝ»Ÿä¹‹é—´çš„对话,但是˜q™ä¸ªå¯¹è¯çš„ç»†èŠ‚åÆˆæ²¡æœ‰åœ¨ç”¨ä¾‹å›¾ä¸­è¡¨˜q°å‡ºæ¥ï¼Œé’ˆå¯¹æ¯ä¸€ä¸ªç”¨ä¾‹æˆ‘们可以用事äšg‹¹æ¥æè¿°˜q™ä¸€å¯¹è¯çš„细节内宏V€‚如在ATM¾pȝ»Ÿä¸­çš„"提款" 用例可以用事件流表述如下åQ?/p>

提款-基本事äšg‹¹?/p>

1. 用户插入信用�/p>

2. 输入密码

3. 输入提款金额

4. 提取现金

5. 退出系¾lŸï¼Œå–回信用å?/p>

但是˜q™åªæè¿°äº†æ‹Æ„¡”¨ä¾‹ä¸­æœ€™åºåˆ©çš„一¿Uæƒ…å†µï¼Œä½œäØ“ä¸€ä¸ªå®žç”¨çš„¾pȝ»ŸåQŒæˆ‘们还必须考虑可能发生的各¿Uå…¶ä»–情况,如信用卡无效、输入密码错、用户帐号中的现金余额不够等åQŒæ‰€æœ‰è¿™äº›å¯èƒ½å‘生的各种情况åQˆåŒ…括正常的和异常的åQ‰è¢«¿UîC¹‹ä¸ºç”¨ä¾‹çš„场景(Scenario)åQŒåœºæ™¯ä¹Ÿè¢«ç§°ä½œæ˜¯ç”¨ä¾‹çš„实ä¾?Instance)。在用例的各¿Uåœºæ™¯ä¸­åQŒæœ€å¸¸è§çš„场景是用基本流(Basic Flow)来描˜q°çš„åQŒå…¶ä»–的场景则是用备选流(Alternative Flow)来描˜q°ã€‚对于ATM¾pȝ»Ÿä¸­çš„"提款"用例åQŒæˆ‘们可以得到如下一些备选流åQ?/p>

提款-备选事件流

备选流一åQšç”¨æˆ·å¯ä»¥åœ¨åŸºæœ¬‹¹ä¸­çš„ä“Q何一步选择退出,转至基本‹¹æ­¥éª?ã€?/p>

备选流二:在基本流步骤1中,用户插入无效信用卡,¾pȝ»Ÿæ˜„¡¤ºé”™è¯¯òq‰™€€å‡ÞZ¿¡ç”¨å¡åQŒç”¨ä¾‹ç»“束ã€?/p>

备选流三:在基本流步骤åQ’中åQŒç”¨æˆ¯‚¾“入错误密码,¾pȝ»Ÿæ˜„¡¤ºé”™è¯¯òq¶æ½Cºç”¨æˆ·é‡æ–°è¾“入密码,重新回到基本‹¹æ­¥éª?åQ›ä¸‰‹Æ¡è¾“入密码错误后åQŒä¿¡ç”¨å¡è¢«ç³»¾lŸæ²¡æ”Óž¼Œç”¨ä¾‹¾l“束ã€?/p>

通过基本‹¹ä¸Žå¤‡é€‰æµçš„组合,ž®±å¯ä»¥å°†ç”¨ä¾‹æ‰€æœ‰å¯èƒ½å‘生的各种场景全部描述清楚。我们在描述用例的事件流的时候,ž®±æ˜¯è¦å°½å¯èƒ½åœ°å°†æ‰€æœ‰å¯èƒ½çš„场景都描˜q°å‡ºæ¥ï¼Œä»¥ä¿è¯éœ€æ±‚的完备性ã€?/p>

1.3 用例æ–ÒŽ³•的优ç‚?/span>

用例æ–ÒŽ³•完全是站在用æˆïLš„角度上(从系¾lŸçš„外部åQ‰æ¥æè¿°¾pȝ»Ÿçš„功能的。在用例æ–ÒŽ³•中,我们把被定义¾pȝ»Ÿçœ‹ä½œæ˜¯ä¸€ä¸ªé»‘½Ž±ï¼Œæˆ‘们òq¶ä¸å…›_¿ƒ¾pȝ»Ÿå†…部是如何完成它所提供的功能的。用例方法首先描˜qîCº†è¢«å®šä¹‰ç³»¾lŸæœ‰å“ªäº›å¤–éƒ¨ä½¿ç”¨è€…ï¼ˆæŠ½è±¡æˆäØ“ActoråQ‰ï¼Œ˜q™äº›ä½¿ç”¨è€…与被定义系¾lŸå‘生交互;针对每一参与者,用例æ–ÒŽ³•又描˜qîCº†¾pȝ»Ÿä¸ø™¿™äº›å‚ä¸Žè€…æä¾›äº†ä»€ä¹ˆæ ·çš„æœåŠ¡ï¼ˆæŠ½è±¡æˆäØ“Use CaseåQ‰ï¼Œæˆ–者说¾pȝ»Ÿæ˜¯å¦‚何被˜q™äº›å‚与者ä‹É用的。所以从用例图中åQŒæˆ‘们可以得到对于被定义¾pȝ»Ÿçš„一个æ€ÖM½“印象ã€?/p>

与传¾lŸçš„功能分解方式相比åQŒç”¨ä¾‹æ–¹æ³•完全是从外部来定义¾pȝ»Ÿçš„功能,它把需求与设计完全分离开来。在面向对象的分析设计方法中åQŒç”¨ä¾‹æ¨¡åž‹ä¸»è¦ç”¨äºŽè¡¨˜q°ç³»¾lŸçš„功能性需求,¾pȝ»Ÿçš„设计主要由对象模型来记录表˜q°ã€‚另外,用例定义了系¾lŸåŠŸèƒ½çš„ä½¿ç”¨çŽ¯å¢ƒä¸Žä¸Šä¸‹æ–‡åQŒæ¯ä¸€ä¸ªç”¨ä¾‹æ˜q°çš„æ˜¯ä¸€ä¸ªå®Œæ•´çš„¾pȝ»ŸæœåŠ¡ã€‚ç”¨ä¾‹æ–¹æ³•æ¯”ä¼ ç»Ÿçš?SRS更易于被用户所理解åQŒå®ƒå¯ä»¥ä½œäؓ开发äh员和用户之间针对¾pȝ»Ÿéœ€æ±‚进行沟通的一个有效手ŒDüc€?/p>

在RUP中,用例被作为整个èÊY件开发流½E‹çš„基础åQŒå¾ˆå¤šç±»åž‹çš„开发活动都把用例作ä¸ÞZ¸€ä¸ªä¸»è¦çš„输入工äšg(Artifact)åQŒå¦‚™å¹ç›®½Ž¡ç†ã€åˆ†æžè®¾è®¡ã€æµ‹è¯•等。根据用例来对目标系¾lŸè¿›è¡Œæµ‹è¯•,可以æ ÒŽ®ç”¨ä¾‹ä¸­æ‰€æè¿°çš„环境和上下文来完整地测试一个系¾lŸæœåŠ¡ï¼Œå¯ä»¥æ ÒŽ®ç”¨ä¾‹çš„各个场æ™?Scenario)来设计测试用例,完全地测试用例的各种场景可以保证‹¹‹è¯•的完备性ã€?/p>



回页�/strong>


2. 建立用例模型

使用用例的方法来描述¾pȝ»Ÿçš„功能需求的˜q‡ç¨‹ž®±æ˜¯ç”¨ä¾‹å»ºæ¨¡åQŒç”¨ä¾‹æ¨¡åž‹ä¸»è¦åŒ…括以下两部分内容åQ?/p>

  • 用例å›?Use Case Diagram)
    ¼‹®å®š¾pȝ»Ÿä¸­æ‰€åŒ…含的参与者、用例和两者之间的对应关系åQŒç”¨ä¾‹å›¾æè¿°çš„æ˜¯å…³äºŽ¾pȝ»ŸåŠŸèƒ½çš„ä¸€ä¸ªæ¦‚˜q°ã€?
  • 用例规约(Use Case Specification)
    针对每一个用例都应该有一个用例规¾U¦æ–‡æ¡£ä¸Žä¹‹ç›¸å¯¹åº”åQŒè¯¥æ–‡æ¡£æè¿°ç”¨ä¾‹çš„细节内宏V€?

在用例徏模的˜q‡ç¨‹ä¸­ï¼Œæˆ‘们廸™®®çš„æ­¥èšæ˜¯å…ˆæ‰¾å‡ºå‚与者,再根据参与者确定每个参与者相关的用例åQŒæœ€åŽå†¾l†åŒ–每一个用例的用例规约ã€?/p>

2.1 å¯ÀL‰¾å‚与è€?/span>

所谓的参与者是指所有存在于¾pȝ»Ÿå¤–部òq¶ä¸Ž¾pȝ»Ÿ˜q›è¡Œäº¤äº’çš„äh或其他系¾lŸã€‚通俗地讲åQŒå‚与者就是我们所要定义系¾lŸçš„使用者。寻扑֏‚与者可以从以下问题入手åQ?/p>

  • ¾pȝ»Ÿå¼€å‘完成之后,有哪些äh会ä‹É用这个系¾lŸï¼Ÿ
  • ¾pȝ»Ÿéœ€è¦ä»Žå“ªäº›äººæˆ–å…¶ä»–¾pȝ»Ÿä¸­èŽ·å¾—æ•°æ®ï¼Ÿ
  • ¾pȝ»Ÿä¼šäؓ哪些人或其他¾pȝ»Ÿæä¾›æ•°æ®åQ?/li>
  • ¾pȝ»Ÿä¼šä¸Žå“ªäº›å…¶ä»–¾pȝ»Ÿç›¸å…³è”?
  • ¾pȝ»Ÿæ˜¯ç”±è°æ¥¾l´æŠ¤å’Œç®¡ç†çš„åQ?/li>

˜q™äº›é—®é¢˜æœ‰åŠ©äºŽæˆ‘ä»¬æŠ½è±¡å‡º¾pȝ»Ÿçš„参与者。对于ATM机的例子åQŒå›ž½{”这些问题可以ä‹É我们扑ֈ°æ›´å¤šçš„参与者:操作员负责维护和½Ž¡ç†ATM机系¾lŸã€ATMæœÞZ¹Ÿéœ€è¦ä¸ŽåŽå°æœåŠ¡å™¨è¿›è¡Œé€šè®¯ä»¥èŽ·å¾—æœ‰å…³ç”¨æˆ·å¸åïLš„相关信息ã€?/p>

2.1.1 ¾pȝ»Ÿè¾¹ç•Œå†›_®šäº†å‚与è€?/strong>

参与者是ç”Þq³»¾lŸçš„边界所军_®šçš„,如果我们所要定义的¾pȝ»Ÿè¾¹ç•Œä»…限于ATM机本íw«ï¼Œé‚£ä¹ˆåŽå°æœåŠ¡å™¨å°±æ˜¯ä¸€ä¸ªå¤–éƒ¨çš„¾pȝ»ŸåQŒå¯ä»¥æŠ½è±¡äؓ一个参与者ã€?/p>

如果我们所要定义的¾pȝ»Ÿè¾¹ç•Œæ‰©å¤§è‡Ïx•´ä¸ªé“¶è¡Œç³»¾lŸï¼ŒATM机和后台服务器都是整个银行系¾lŸçš„一部分åQŒè¿™æ—¶å€™åŽå°æœåС噍ž®×ƒ¸å†è¢«æŠ½è±¡æˆäؓ一个参与者ã€?/p>

值得注意的是åQŒç”¨ä¾‹å¾æ¨¡æ—¶ä¸è¦ž®†ä¸€äº›ç³»¾lŸçš„¾l„成¾l“æž„ä½œäØ“å‚ä¸Žè€…æ¥˜q›è¡ŒæŠ½è±¡åQŒå¦‚在ATM机系¾lŸä¸­åQŒæ‰“印机只是¾pȝ»Ÿçš„一个组成部分,不应ž®†å®ƒæŠ½è±¡æˆä¸€ä¸ªç‹¬ç«‹çš„参与者;在一个MIS½Ž¡ç†¾pȝ»Ÿä¸­ï¼Œæ•°æ®åº“ç³»¾lŸå¾€å¾€åªä½œä¸ºç³»¾lŸçš„一个组成部分,一般不ž®†å…¶å•独抽象成一个参与者ã€?/p>

2.1.2 ç‰ÒŽ®Šçš„参与者――系¾lŸæ—¶é’?/strong>

有时候我们需要在¾pȝ»Ÿå†…部定时地执行一些操作,如检‹¹‹ç³»¾lŸèµ„源ä‹É用情å†üc€å®šæœŸåœ°ç”Ÿæˆ¾lŸè®¡æŠ¥è¡¨½{‰ç­‰ã€‚从表面上看åQŒè¿™äº›æ“ä½œåƈ不是由外部的人或¾pȝ»Ÿè§¦å‘的,应该怎样用用例方法来表述˜q™ä¸€¾cÕdŠŸèƒ½éœ€æ±‚å‘¢åQŸå¯¹äºŽè¿™¿Uæƒ…况,我们可以抽象å‡ÞZ¸€ä¸ªç³»¾lŸæ—¶é’Ÿæˆ–定时器参与者,利用该参与者来触发˜q™ä¸€¾cÕd®šæ—¶æ“ä½œã€‚从逻辑上,˜q™ä¸€å‚与者应该被理解成是¾pȝ»Ÿå¤–部的,由它来触发系¾lŸæ‰€æä¾›çš„用例对话ã€?/p>

2.2 ¼‹®å®šç”¨ä¾‹

扑ֈ°å‚与者之后,我们ž®±å¯ä»¥æ ¹æ®å‚与者来¼‹®å®š¾pȝ»Ÿçš„用例,主要是看各参与者需要系¾lŸæä¾›ä»€ä¹ˆæ ·çš„æœåŠ¡ï¼Œæˆ–è€…è¯´å‚ä¸Žè€…æ˜¯å¦‚ä½•ä½¿ç”¨¾pȝ»Ÿçš„。寻扄¡”¨ä¾‹å¯ä»¥ä»Žä»¥ä¸‹é—®é¢˜å…¥æ‰‹åQˆé’ˆå¯Òޝä¸€ä¸ªå‚与者)åQ?/p>

  • å‚ä¸Žè€…äØ“ä»€ä¹ˆè¦ä½¿ç”¨è¯¥ç³»¾lŸï¼Ÿ
  • 参与者是否会在系¾lŸä¸­åˆ›å¾ã€ä¿®æ”V€åˆ é™¤ã€è®¿é—®ã€å­˜å‚¨æ•°æ®ï¼Ÿå¦‚果是的话,参与者又是如何来完成˜q™äº›æ“ä½œçš„?
  • 参与者是否会ž®†å¤–部的某些事äšg通知¾l™è¯¥¾pȝ»ŸåQ?/li>
  • ¾pȝ»Ÿæ˜¯å¦ä¼šå°†å†…部的某些事仉™€šçŸ¥è¯¥å‚与者?

¾l¼åˆä»¥ä¸Šæ‰€˜qŽÍ¼ŒATM¾pȝ»Ÿçš„用例图可表½Cºå¦‚下,



在用例的抽取˜q‡ç¨‹ä¸­ï¼Œå¿…须注意åQšç”¨ä¾‹å¿…™åÀL˜¯ç”±æŸä¸€ä¸ªä¸»è§’触发而äñ”生的‹zÕdЍåQŒå³æ¯ä¸ªç”¨ä¾‹è‡›_°‘应该涉及一个主角。如果存在与主角不进行交互的用例åQŒå°±å¯ä»¥è€ƒè™‘ž®†å…¶òq¶å…¥å…¶ä»–用例åQ›æˆ–者是‹‚€æŸ¥è¯¥ç”¨ä¾‹ç›¸å¯¹åº”的参与者是否被遗漏åQŒå¦‚果是åQŒåˆ™è¡¥ä¸Šè¯¥å‚与者。反之,每个参与者也必须臛_°‘涉及åˆîC¸€ä¸ªç”¨ä¾‹ï¼Œå¦‚果发现有不与ä“Q何用例相兌™”的参与者存在,ž®±åº”该考虑该参与者是如何与系¾lŸå‘生对话的åQŒæˆ–者由参与者确定一个新的用例,或者该参与者是一个多余的模型元素åQŒåº”该将其删除ã€?/p>

可视化徏模的主要目的之一ž®±æ˜¯è¦å¢žå¼ºå›¢é˜Ÿçš„æ²Ÿé€šï¼Œç”¨ä¾‹æ¨¡åž‹å¿…须是易于理解的。用例徏模往往是一个团队开发的˜q‡ç¨‹åQŒç³»¾lŸåˆ†æžå‘˜åœ¨å¾æ¨¡è¿‡½E‹ä¸­å¿…须注意参与者和用例的名¿U°åº”该符合一定的命名¾U¦å®šåQŒè¿™æ äh•´ä¸ªç”¨ä¾‹æ¨¡åž‹æ‰èƒ½å¤Ÿ½W¦åˆä¸€å®šçš„风格。如参与者的名称一般都是名词,用例名称一般都是动宾词¾l„ç­‰ã€?/p>

对于同一个系¾lŸï¼Œä¸åŒçš„äh对于参与者和用例都可能有不同的抽象结果,因而得åˆîC¸åŒçš„用例模型。我们需要在多个用例模型æ–ÒŽ¡ˆä¸­é€‰æ‹©ä¸€¿U?最ä½?åQˆæˆ–"较佳"åQ‰çš„¾l“æžœåQŒä¸€ä¸ªå¥½çš„用例模型应该能够容易被不同的涉众所理解åQŒåƈ且不同的涉众对于同一用例模型的理解应该是一致的ã€?/p>

2.3 描述用例规约

应该避免˜q™æ ·ä¸€¿Uè¯¯è§£â€•―认为由参与者和用例构成的用例图ž®±æ˜¯ç”¨ä¾‹æ¨¡åž‹åQŒç”¨ä¾‹å›¾åªæ˜¯åœ¨æ€ÖM½“上大致描˜qîCº†¾pȝ»Ÿæ‰€èƒ½æä¾›çš„各种服务åQŒè®©æˆ‘们对于¾pȝ»Ÿçš„功能有一个æ€ÖM½“的认识。除此之外,我们˜q˜éœ€è¦æ˜q°æ¯ä¸€ä¸ªæœ‰ä¾‹çš„详细信息åQŒè¿™äº›ä¿¡æ¯åŒ…含在用例规约中,用例模型是由用例囑֒Œæ¯ä¸€ä¸ªç”¨ä¾‹çš„详细描述――用例规¾U¦æ‰€¾l„成的。RUP中提供了用例规约的模板,每一个用例的用例规约都应该包含以下内容:

  • ½Ž€è¦è¯´æ˜?(Brief Description)
    ½Ž€è¦ä»‹¾lè¯¥ç”¨ä¾‹çš„作用和目的ã€?
  • 事äšg‹¹?(Flow of Event)
    包括基本‹¹å’Œå¤‡é€‰æµåQŒäº‹ä»¶æµåº”该表示出所有的场景ã€?
  • 用例场景 (Use-Case Scenario)
    包括成功场景和失败场景,场景主要是由基本‹¹å’Œå¤‡é€‰æµ¾l„合而成的ã€?
  • ç‰ÒŽ®Šéœ€æ±?(Special Requirement)
    描述与该用例相关的非功能性需求(包括性能、可靠性、可用性和可扩展性等åQ‰å’Œè®¾è®¡¾U¦æŸåQˆæ‰€ä½¿ç”¨çš„æ“ä½œç³»¾lŸã€å¼€å‘å·¥å…ïL­‰åQ‰ã€?
  • 前置条äšg (Pre-Condition)
    执行用例之前¾pȝ»Ÿå¿…须所处的状态ã€?
  • 后置条äšg (Post-Condition)
    用例执行完毕后系¾lŸå¯èƒ½å¤„于的一¾l„状态ã€?

用例规约基本上是用文本方式来表述的,ä¸ÞZº†æ›´åŠ æ¸…æ™°åœ°æ˜qîCº‹ä»¶æµåQŒä¹Ÿå¯ä»¥é€‰æ‹©ä½¿ç”¨çŠ¶æ€å›¾ã€æ´»åŠ¨å›¾æˆ–åºåˆ—å›¾æ¥è¾…åŠ©è¯´æ˜Žã€‚åªè¦æœ‰åŠ©äºŽè¡¨è¾¾çš„ç®€‹zæ˜Žäº†ï¼Œž®±å¯ä»¥åœ¨ç”¨ä¾‹ä¸­ä“Q意粘贴用æˆïL•Œé¢å’Œ‹¹ç¨‹çš„图形化昄¡¤ºæ–¹å¼åQŒæˆ–是其他图形。如‹zÕdŠ¨å›¾æœ‰åŠ©äºŽæè¿°å¤æ‚çš„å†³½{–流½E‹ï¼ŒçŠ¶æ€è{¿UÕd›¾æœ‰åŠ©äºŽæ˜qîC¸ŽçŠ¶æ€ç›¸å…³çš„¾pȝ»Ÿè¡ŒäØ“åQŒåºåˆ—图适合于描˜q°åŸºäºŽæ—¶é—´é¡ºåºçš„æ¶ˆæ¯ä¼ é€’ã€?/p>

2.3.1 基本‹¹?/strong>

基本‹¹æ˜q°çš„æ˜¯è¯¥ç”¨ä¾‹æœ€æ­£å¸¸çš„一¿Uåœºæ™¯ï¼Œåœ¨åŸºæœ¬æµä¸­ç³»¾lŸæ‰§è¡Œä¸€¾pÕdˆ—‹zÕdŠ¨æ­¥éª¤æ¥å“åº”å‚ä¸Žè€…æå‡ºçš„æœåŠ¡è¯äh±‚。我们徏议用以下格式来描˜q°åŸºæœ¬æµåQ?/p>

1) 每一个步骤都需要用数字¾~–号以清楚地标明步骤的先后顺序ã€?/p>

2) 用一句简短的标题来概括每一步骤的主要内容,˜q™æ ·é˜…读者可以通过‹¹è§ˆæ ‡é¢˜æ¥å¿«é€Ÿåœ°äº†è§£ç”¨ä¾‹çš„主要步骤。在用例建模的早期,我们也只需要描˜q°åˆ°äº‹äšg‹¹æ­¥éª¤æ ‡é¢˜è¿™ä¸€å±‚,以免˜q‡æ—©åœ°é™·å…¥åˆ°ç”¨ä¾‹æè¿°çš„细节中厅R€?/p>

3) 当整个用例模型基本稳定之后,我们再针å¯Òޝä¸€æ­¥éª¤è¯¦ç»†æè¿°å‚与者和¾pȝ»Ÿä¹‹é—´æ‰€å‘生的交互。徏议采用双å?roundtrip)描述法来保证描述的完整性,åÏx¯ä¸€æ­¥éª¤éƒ½éœ€è¦ä»Žæ­£åä¸¤ä¸ªæ–šw¢æ¥æ˜q?(1)参与者向¾pȝ»Ÿæäº¤äº†ä»€ä¹ˆä¿¡æ¯ï¼›(2)å¯ÒŽ­¤¾pȝ»Ÿæœ‰ä»€ä¹ˆæ ·çš„响应。具体例子请参见附录ã€?/p>

在描˜q°å‚与者和¾pȝ»Ÿä¹‹é—´çš„信息交换时åQŒéœ€æŒ‡å‡ºæ¥å›žä¼ é€’的具体信息。例如,只表˜q°å‚与者输入了客户信息ž®×ƒ¸å¤Ÿæ˜Ž¼‹®ï¼Œæœ€å¥½æ˜Ž¼‹®åœ°è¯´å‚与者输入了客户姓名和地址。通常可以利用词汇表让用例的复杂性保持在可控范围内,可以在词汇表中定义客户信息等内容åQŒä‹É用例不至于陷入过多的¾l†èŠ‚ã€?/p>

2.3.2 备选流

备选流负责描述用例执行˜q‡ç¨‹ä¸­å¼‚常的或偶ž®”发生的一些情况,备选流和基本流的组合应该能够覆盖该用例所有可能发生的场景。在描述备选流æ—Óž¼Œåº”该包括以下几个要素åQ?/p>

1) èµïL‚¹åQšè¯¥å¤‡é€‰æµä»Žäº‹ä»¶æµçš„哪一步开始;

2) 条äšgåQšåœ¨ä»€ä¹ˆæ¡ä»¶ä¸‹ä¼šè§¦å‘该备选流åQ?/p>

3) 动作åQšç³»¾lŸåœ¨è¯¥å¤‡é€‰æµä¸‹ä¼šé‡‡å–哪些动作åQ?/p>

4) 恢复åQšè¯¥å¤‡é€‰æµ¾l“束之后åQŒè¯¥ç”¨ä¾‹åº”如何ç‘ô¾l­æ‰§è¡Œã€?/p>

备选流的描˜q°æ ¼å¼å¯ä»¥ä¸ŽåŸºæœ¬‹¹çš„æ ¼å¼ä¸€è‡ß_¼Œä¹Ÿéœ€è¦ç¼–å·åÆˆä»¥æ ‡é¢˜æ¦‚˜q°å…¶å†…容åQŒç¼–号前可以加以字母前缀A(Alternative)以示与基本流步骤相区别ã€?/p>

2.3.3 用例场景

用例在实际执行的时候会有很多的不同情况发生åQŒç§°ä¹‹äؓ用例场景åQ›ä¹Ÿå¯ä»¥è¯´åœºæ™¯æ˜¯ç”¨ä¾‹çš„实例,我们在描˜q°ç”¨ä¾‹çš„æ—¶å€™è¦è¦†ç›–所有的用例场景åQŒå¦åˆ™å°±æœ‰å¯èƒ½å¯¼è‡´éœ€æ±‚的遗漏。在用例规约中,场景的描˜q°å¯ä»¥ç”±åŸºæœ¬‹¹å’Œå¤‡é€‰æµçš„组合来表示。场景既可以帮助我们防止需求的遗漏åQŒåŒæ—¶ä¹Ÿå¯ä»¥å¯¹åŽ¾l­çš„开发工作è“v到很大的帮助åQšå¼€å‘äh员必™åÕd®žçŽ°æ‰€æœ‰çš„åœºæ™¯ã€æµ‹è¯•äh员可以根据用例场景来设计‹¹‹è¯•用例ã€?/p>

2.3.4 ç‰ÒŽ®Šéœ€æ±?/strong>

ç‰ÒŽ®Šéœ€æ±‚é€šå¸¸æ˜¯éžåŠŸèƒ½æ€§éœ€æ±‚ï¼Œå®ƒäØ“ä¸€ä¸ªç”¨ä¾‹æ‰€ä¸“æœ‰åQŒä½†ä¸é€‚合在用例的事äšg‹¹æ–‡æœ¬ä¸­˜q›è¡Œè¯´æ˜Žã€‚特ŒDŠéœ€æ±‚的例子包括法律或法规方面的需求、应用程序标准和所构徏¾pȝ»Ÿçš„质量属性(包括可用性、可靠性、性能或支持性需求等åQ‰ã€‚此外,其他一些设计约束,如操作系¾lŸåŠçŽ¯å¢ƒã€å…¼å®ÒŽ€§éœ€æ±‚ç­‰åQŒä¹Ÿå¯ä»¥åœ¨æ­¤èŠ‚ä¸­è®°å½•ã€?/p>

需要注意的是,˜q™é‡Œè®°å½•的是专属于该用例的特ŒDŠéœ€æ±‚;对于一些全局的非功能性需求和设计¾U¦æŸåQŒå®ƒä»¬åƈ不是该用例所专有的,应把它们记录在《补充规¾U¦ã€‹ä¸­ã€?/p>

2.3.5 前置和后¾|®æ¡ä»?/strong>

前置条äšg是执行用例之前必™åÕd­˜åœ¨çš„¾pȝ»ŸçŠ¶æ€ï¼ŒåŽç½®æ¡äšg是用例一执行完毕后系¾lŸå¯èƒ½å¤„于的一¾l„状态ã€?/p>

2.4 ‹‚€æŸ¥ç”¨ä¾‹æ¨¡åž?/span>

用例模型完成之后åQŒå¯ä»¥å¯¹ç”¨ä¾‹æ¨¡åž‹˜q›è¡Œ‹‚€æŸ¥ï¼Œçœ‹çœ‹æ˜¯å¦æœ‰é—漏或错误之处。主要可以从以下几个斚w¢æ¥è¿›è¡Œæ£€æŸ¥ï¼š

  • 功能需求的完备æ€?
    现有的用例模型是否完整地描述了系¾lŸåŠŸèƒ½ï¼Œ˜q™ä¹Ÿæ˜¯æˆ‘们判断用例徏模工作是否结束的标志。如果发现还有系¾lŸåŠŸèƒ½æ²¡æœ‰è¢«è®°å½•åœ¨çŽ°æœ‰çš„ç”¨ä¾‹æ¨¡åž‹ä¸­ï¼Œé‚£ä¹ˆæˆ‘ä»¬ž®±éœ€è¦æŠ½è±¡ä¸€äº›æ–°çš„用例来记录˜q™äº›éœ€æ±‚,或是ž®†ä»–们归¾U›_œ¨ä¸€äº›çŽ°æœ‰çš„ç”¨ä¾‹ä¹‹ä¸­ã€?
  • 模型是否易于理解
    用例模型最大的优点ž®±åœ¨äºŽå®ƒåº”该易于被不同的涉众所理解åQŒå› è€Œç”¨ä¾‹å¾æ¨¡æœ€ä¸»è¦çš„æŒ‡å¯¼åŽŸåˆ™å°±æ˜¯å®ƒçš„å¯ç†è§£æ€§ã€‚ç”¨ä¾‹çš„¾_’度、个æ•îC»¥åŠæ¨¡åž‹å…ƒç´ ä¹‹é—´çš„关系复杂½E‹åº¦éƒ½åº”该由该指导原则决定ã€?
  • 是否存在不一致æ€?
    ¾pȝ»Ÿçš„用例模型是由多个系¾lŸåˆ†æžå‘˜ååŒå®Œæˆçš„,模型本èín也是由多个工件所¾l„成的,所以我们要特别注意不同工äšg之前是否存在前后矛盾或冲½Hçš„地方åQŒé¿å…åœ¨æ¨¡åž‹å†…部产生不一致性。不一致性会直接影响到需求定义的准确性ã€?
  • 避免二义性语ä¹?
    好的需求定义应该是无二义性的åQŒå³ä¸åŒçš„äh对于同一需求的理解应该是一致的。在用例规约的描˜qîC¸­åQŒåº”该避免定义含义模¾pŠçš„需求,åÏx— äºŒä¹‰æ€§ã€?




回页�/strong>


3. ¾pȝ»Ÿéœ€æ±?/span>

RUP中根据FURPS+模型ž®†ç³»¾lŸéœ€æ±‚分ä¸ÞZ»¥ä¸‹å‡ ¾c»ï¼š

  • 功能(Functionality)
  • 可用æ€?Usability)
  • 可靠æ€?Reliability)
  • 性能(Performance)
  • 可支持æ€?Supportability)
  • 设计¾U¦æŸ½{?/li>

除了½W¬ä¸€™å¹åŠŸèƒ½æ€§éœ€æ±‚ä¹‹å¤–çš„å…¶ä»–éœ€æ±‚éƒ½å½’ä¹‹ä¸ºéžåŠŸèƒ½æ€§éœ€æ±‚ã€?/p>

3.1 需求工仉™›†

用例模型主要用于描述¾pȝ»Ÿçš„功能性需求,对于其他的非功能性需要用其他文档来记录。RUP中定义了如下的需求工仉™›†åˆã€?/p>

  • 用例模型åQšè®°å½•功能性需æ±?
    • 用例图:描述参与者和用例之间的关¾p?/li>
    • 用例规约åQšæ˜q°æ¯ä¸€ä¸ªç”¨ä¾‹çš„¾l†èŠ‚ä¿¡æ¯
  • 补充规约åQšè®°å½•一些全局性的功能需求、非功能性需求和设计¾U¦æŸ½{?/li>
  • 词汇表:记录一些系¾lŸéœ€æ±‚相关的术语

在实际应用中åQŒé™¤äº†è¿™äº›å·¥ä»¶ä¹‹å¤–,我们˜q˜å¯ä»¥æ ¹æ®å®žé™…需求灵‹z»é€‰ç”¨å…¶ä»–å½¢å¼çš„æ–‡æ¡£æ¥è¡¥å……è¯´æ˜Žéœ€æ±‚ã€‚åÆˆä¸æ˜¯æ‰€æœ‰çš„¾pȝ»Ÿéœ€æ±‚都适保合用用例模型来描˜q°çš„åQŒå¦‚¾~–译器,我们很难用用例方法来表述它所处理的语­a€çš„æ–¹æ³•规则,在这¿Uæƒ…况下åQŒé‡‡ç”¨ä¼ ¾lŸçš„BNF范式来表˜q°æ›´åŠ åˆé€‚ä¸€äº›ã€‚åœ¨ç”µä¿¡è½¯äšg行业中,很多电信标准都是采用SDL语言来描˜q°çš„åQŒæˆ‘们也不必用UML来改写这些标准(UML对SDL存在着˜q™æ ·çš„å…¼å®ÒŽ€§ï¼‰åQŒåªéœ€ž®†SDL形式的电信标准作为需求工件之一åQŒåœ¨å…¶ä»–å·¥äšg中对其加以引用就可以了。æ€ÖM¹‹åQŒä¸‡ä¸‡ä¸å¯æ‹˜æ³¥äºŽç”¨ä¾‹å»ºæ¨¡çš„åŞ式,应灵‹z»è¿ç”¨å„¿Uæ–¹å¼çš„长处ã€?/p>

3.2 补充规约

补充规约记录那些在用例模型中不易表述的系¾lŸéœ€æ±‚,主要包括以下内容ã€?/p>

  • 功能æ€?
    功能性需求主要在用例模型中刻画,但是也有部分需求不适合在用例中表述。有些功能性需求是全局性的åQŒé€‚用于所有的用例åQŒå¦‚出错处理、I18N支持½{‰ï¼Œæˆ‘们不需要在所有的用例中描˜q°è¿™äº›åŠŸèƒ½æ€§éœ€æ±‚ï¼Œåªéœ€è¦åœ¨è¡¥å……è§„çº¦ä¸­ç»Ÿä¸€æè¿°ž®±å¯ä»¥äº†ã€?
  • 可用æ€?
    记录所有可用性相关的需求,如系¾lŸçš„使用者所需要的培训旉™—´ã€æ˜¯å¦åº”附合一些常见的可用性标准如Windows界面风格½{‰ã€?
  • 可靠æ€?
    定义¾pȝ»Ÿå¯é æ€§ç›¸å…³çš„各种指标åQŒåŒ…括:
    • 可用性:指出可用旉™—´ç™‘Öˆ†æ¯?xx.xx%)åQŒç³»¾lŸå¤„于ä‹É用、维护、降¾U§æ¨¡å¼ç­‰æ“ä½œçš„小时数åQ?/li>
    • òq›_‡æ•…障间隔旉™—´(MTBF)åQšé€šå¸¸è¡¨ç¤ºä¸ºå°æ—¶æ•°åQŒä½†ä¹Ÿå¯è¡¨ç¤ºä¸ºå¤©æ•°ã€æœˆæ•°æˆ–òq´æ•°åQ?/li>
    • òq›_‡ä¿®å¤æ—‰™—´(MTTR)åQšç³»¾lŸåœ¨å‘生故障后可以暂停运行的旉™—´åQ?/li>
    • ¾_„¡¡®åº¦ï¼šæŒ‡å‡º¾pȝ»Ÿè¾“出要求具备的精密度åQˆåˆ†è¾¨çއåQ‰å’Œ¾_„¡¡®åº¦ï¼ˆæŒ‰ç…§æŸä¸€å·²çŸ¥çš„æ ‡å‡†ï¼‰åQ?/li>
    • 最高错误或¾~ºé™·çŽ‡ï¼šé€šå¸¸è¡¨ç¤ºä¸ºbugs/KLOCåQˆæ¯åƒè¡Œä»£ç çš„错误数目)或bugs/function-pointåQˆæ¯ä¸ªåŠŸèƒ½ç‚¹çš„é”™è¯¯æ•°ç›®ï¼‰ã€?/li>
  • 性能
    记录¾pȝ»Ÿæ€§èƒ½ç›¸å…³çš„各¿UæŒ‡æ ‡ï¼ŒåŒ…括åQ?
    • 对事务的响应旉™—´åQˆåã^均、最长)åQ?/li>
    • 吞吐量(例如每秒处理的事务数åQ‰ï¼›
    • 定w‡åQˆä¾‹å¦‚ç³»¾lŸå¯ä»¥å®¹¾U³çš„客户或事务数åQ‰ï¼›
    • 降çñ”模式åQˆå½“¾pȝ»Ÿä»¥æŸ¿UåŞ式降¾U§æ—¶å¯æŽ¥å—çš„˜qè¡Œæ¨¡å¼åQ‰ï¼›
    • 资源利用情况åQšå†…存、磁盘、通信½{‰ã€?/li>
  • 可支持æ€?
    定义所有与¾pȝ»Ÿçš„可支持性或可维护性相关的需求,其中包括¾~–码标准、命名约定、类库、如何来对系¾lŸè¿›è¡Œç»´æŠ¤æ“ä½œå’Œç›¸åº”的维护实用工å…ïL­‰ã€?
  • 设计¾U¦æŸ
    设计¾U¦æŸä»£è¡¨å·²ç»æ‰¹å‡†òq¶å¿…™å»éµå¾ªçš„设计军_®šåQŒå…¶ä¸­åŒ…括èÊY件开发流½E‹ã€å¼€å‘工兗÷€ç³»¾lŸæž„架、编½E‹è¯­­a€ã€ç¬¬ä¸‰æ–¹æž„äšg¾cÕdº“、运行åã^台和数据库系¾lŸç­‰½{‰ã€?

3.3 词汇�/span>

词汇表主要用于定义项目特定的术语åQŒå®ƒæœ‰åŠ©äºŽå¼€å‘äh员对™å¹ç›®ä¸­æ‰€ç”¨çš„æœ¯è¯­æœ‰ç»Ÿä¸€çš„理解和使用åQŒå®ƒä¹Ÿæ˜¯åŽç®‹é˜¶æ®µä¸­è¿›è¡Œå¯¹è±¡æŠ½è±¡çš„基础ã€?/p>



回页�/strong>


4. 调整用例模型

在一般的用例图中åQŒæˆ‘们只表述参与者和用例之间的关¾p»ï¼Œå›_®ƒä»¬ä¹‹é—´çš„通讯兌™”。除此之外,我们˜q˜å¯ä»¥æ˜q°å‚与者与参与者之间的泛化 (generalization)、用例和用例之间的包å?include)、扩å±?extend)和泛åŒ?generalization)关系。我们利用这些关¾pÀL¥è°ƒæ•´å·²æœ‰çš„用例模型,把一些公å…Þqš„信息抽取出来重用åQŒä‹É得用例模型更易于¾l´æŠ¤ã€‚但是在应用中要ž®å¿ƒé€‰ç”¨˜q™äº›å…³ç³»åQŒä¸€èˆ¬æ¥è¯´è¿™äº›å…³¾p»éƒ½ä¼šå¢žåŠ ç”¨ä¾‹å’Œå…³ç³»çš„ä¸ªæ•ŽÍ¼Œä»Žè€Œå¢žåŠ ç”¨ä¾‹æ¨¡åž‹çš„å¤æ‚åº¦ã€‚è€Œä¸”ä¸€èˆ¬éƒ½æ˜¯åœ¨ç”¨ä¾‹æ¨¡åž‹å®Œæˆä¹‹åŽæ‰å¯¹ç”¨ä¾‹æ¨¡åž‹˜q›è¡Œè°ƒæ•´åQŒæ‰€ä»¥åœ¨ç”¨ä¾‹å»ºæ¨¡çš„初期不必要急于抽象用例之间的关¾p…R€?/p>

4.1 参与者之间的关系

参与者之间可以有泛化(Generalization)关系åQˆæˆ–¿UîCØ“"¾l§æ‰¿"关系åQ‰ã€‚例如在需求分析中常见的权限控刉™—®é¢˜ï¼ˆå¦‚下图所½Cºï¼‰åQŒä¸€èˆ¬çš„用户只可以ä‹É用一些常规的操作åQŒè€Œç®¡ç†å‘˜é™¤äº†å¸¸è§„操作之外˜q˜éœ€è¦è¿›è¡Œä¸€äº›ç³»¾lŸç®¡ç†å·¥ä½œï¼Œæ“ä½œå‘˜æ—¢å¯ä»¥˜q›è¡Œå¸¸è§„操作又可以进行一些配¾|®æ“ä½œã€?/p>

在这个例子中我们会发现管理员和操作员都是一¿Uç‰¹ŒDŠçš„用户åQŒä»–们拥有普通用æˆäh‰€æ‹¥æœ‰çš„全部权限,此外他们˜q˜æœ‰è‡ªå·±ç‹¬æœ‰çš„æƒé™ã€‚这里我们可˜q›ä¸€æ­¥æŠŠæ™®é€šç”¨æˆ·å’Œ½Ž¡ç†å‘˜ã€æ“ä½œå‘˜ä¹‹é—´çš„å…³¾pÀLŠ½è±¡æˆæ³›åŒ–(Generalization)关系åQŒç®¡ç†å‘˜å’Œæ“ä½œå‘˜å¯ä»¥¾l§æ‰¿æ™®é€šç”¨æˆïLš„全部ç‰ÒŽ€§ï¼ˆåŒ…括权限åQ‰ï¼Œä»–们又可以有自己独有的特性(如操作、权限等åQ‰ã€‚这样可以显著减速少用例图中通讯兌™”的个敎ͼŒ½Ž€åŒ–用例模型,使之更易于理解ã€?/p>

4.2 用例之间的关¾p?/span>

用例描述的是¾pȝ»Ÿå¤–部可见的行为,是系¾lŸäؓ某一个或几个参与者提供的一ŒDµå®Œæ•´çš„æœåŠ¡ã€‚ä»ŽåŽŸåˆ™ä¸Šæ¥è®ÔŒ¼Œç”¨ä¾‹ä¹‹é—´éƒ½æ˜¯òq¶åˆ—的,它们之间òq¶ä¸å­˜åœ¨ç€åŒ…含从属关系。但是从保证用例模型的可¾l´æŠ¤æ€§å’Œä¸€è‡´æ€§è§’度来看,我们可以在用例之间抽象出包含(include)、扩å±?extend)和泛åŒ?(generalization)˜q™å‡ ¿Uå…³¾p…R€‚这几种关系都是从现有的用例中抽取出公共的那部分信息åQŒç„¶åŽé€šåŽ˜q‡ä¸åŒçš„æ–ÒŽ³•来重用这部公å…׃¿¡æ¯ï¼Œä»¥å‡ž®‘模型维护的工作量ã€?/p>

4.2.1 包含(include)

包含关系是通过在关联关¾pÖM¸Šåº”用<<include>>构造型来表½Cºçš„åQŒå¦‚下图所½Cºã€‚它所表示的语义是指基¼‹€ç”¨ä¾‹(Base)会用到被包含用例(Inclusion)åQŒå…·ä½“地è®ÔŒ¼Œž®±æ˜¯ž®†è¢«åŒ…含用例的事件流插入到基¼‹€ç”¨ä¾‹çš„事件流中ã€?/p>

包含关系是UML1.3中的表述åQŒåœ¨UML1.1中,同等语义的关¾p»è¢«è¡¨è¿°ä¸ÞZ‹Éç”?uses)åQŒå¦‚下图ã€?/p>

åœ?ATMæœÞZ¸­åQŒå¦‚果查询、取现、è{帐这三个用例都需要打åîC¸€ä¸ªå›žæ‰§ç»™å®¢æˆ·åQŒæˆ‘们就可以把打印回执这一部分内容提取出来åQŒæŠ½è±¡æˆä¸ÞZ¸€ä¸ªå•独的用例"打印回执"åQŒè€ŒåŽŸæœ‰çš„æŸ¥è¯¢ã€å–çŽ°ã€è{帐三个例都会包含˜q™ä¸ªç”¨ä¾‹ã€‚每当以后要å¯Òމ“印回执部分的需求进行修æ”ÒŽ—¶åQŒå°±åªéœ€è¦æ”¹åŠ¨ä¸€ä¸ªç”¨ä¾‹ï¼Œè€Œä¸ç”¨åœ¨æ¯ä¸€ä¸ªç”¨ä¾‹éƒ½ä½œç›¸åº”ä¿®æ”¹ï¼Œ˜q™æ ·ž®±æé«˜äº†ç”¨ä¾‹æ¨¡åž‹çš„可¾l´æŠ¤æ€§ã€?/p>

在基¼‹€ç”¨ä¾‹çš„事件流中,我们只需要引用被包含用例卛_¯ã€?/p>

查询-基本事äšg‹¹?/p>

1. 用户插入信用�/p>

2. 输入密码

3. 选择查询

4. 查看帐号余额

5. 包含用例"打印回执"

6. 退出系¾lŸï¼Œå–回信用å?/p>

在这个例子中åQŒå¤šä¸ªç”¨ä¾‹éœ€è¦ç”¨åˆ°åŒä¸€ŒDµè¡Œä¸ºï¼Œæˆ‘们可以把这ŒDµå…±åŒçš„è¡ŒäØ“å•ç‹¬æŠ½è±¡æˆäØ“ä¸€ä¸ªç”¨ä¾‹ï¼Œç„¶åŽè®©å…¶ä»–çš„ç”¨ä¾‹æ¥åŒ…å«è¿™ä¸€ç”¨ä¾‹ã€‚ä»Žè€Œé¿å…åœ¨å¤šä¸ªç”¨ä¾‹ä¸­é‡å¤æ€§åœ°æè¿°åŒä¸€ŒDµè¡Œä¸ºï¼Œä¹Ÿå¯ä»¥é˜²æ­¢è¯¥ŒDµè¡Œä¸ºåœ¨å¤šä¸ªç”¨ä¾‹ä¸­çš„æè¿°å‡ºçŽ°ä¸ä¸€è‡´æ€§ã€‚å½“éœ€è¦ä¿®æ”¹è¿™ŒDµå…¬å…Þqš„需求时åQŒæˆ‘们也只需要修改一个用例,避免同时修改多个用例而äñ”生的不一致性和重复性工作ã€?/p>

有时当某一个用例的事äšg‹¹è¿‡äºŽå¤æ‚æ—¶åQŒäؓ了简化用例的描述åQŒæˆ‘们也可以把某一ŒDµäº‹ä»¶æµæŠ½è±¡æˆäؓ一个被包含的用例。这¿Uæƒ…å†ëб»ä¼égºŽåœ¨è¿‡½E‹è®¾è®¡è¯­­a€ä¸­ï¼Œž®†ç¨‹åºçš„æŸä¸€ŒD늮—法封装成一个子˜q‡ç¨‹åQŒç„¶åŽå†ä»Žä¸»½E‹åºä¸­è°ƒç”¨è¿™ä¸€å­è¿‡½E‹ã€?/p>

4.2.2 扩展(extend)

扩展åQˆextendåQ‰å…³¾pÕd¦‚下图所½Cºï¼ŒåŸºç¡€ç”¨ä¾‹(Base)中定义有一臛_¤šä¸ªå·²å‘½åçš„æ‰©å±•点åQŒæ‰©å±•å…³¾pÀL˜¯æŒ‡å°†æ‰©å±•用例(Extension)的事件流在一定的条äšg下按照相应的扩展ç‚ÒŽ’入到基础用例(Base)中。对于包含关¾p»è€Œè¨€åQŒå­ç”¨ä¾‹ä¸­çš„事äšg‹¹æ˜¯ä¸€å®šæ’入到基础用例中去的,òq¶ä¸”插入点只有一个。而扩展关¾pÕd¯ä»¥æ ¹æ®ä¸€å®šçš„æ¡äšg来决定是否将扩展用例的事件流插入基础用例事äšg‹¹ï¼Œòq¶ä¸”插入点可以有多个ã€?/p>

例如对于电话业务åQŒå¯ä»¥åœ¨åŸºæœ¬é€šè¯(Call)业务上扩展出一些增å€ég¸šåС如åQšå‘¼å«ç­‰å¾?Call Waiting)和呼叫è{¿U?Call Transfer)。我们可以用扩展关系ž®†è¿™äº›ä¸šåŠ¡çš„ç”¨ä¾‹æ¨¡åž‹æè¿°å¦‚ä¸‹ã€?/p>



在这个例子中åQŒå‘¼å«ç­‰å¾…和呼叫转移都是对基本通话用例的扩展,但是˜q™ä¸¤ä¸ªç”¨ä¾‹åªæœ‰åœ¨ä¸€å®šçš„æ¡äšg下(如应½{”方正忙或应½{”方无应½{”)才会ž®†è¢«æ‰©å±•用例的事件流嵌入基本通话用例的扩展点åQŒåƈ重用基本通话用例中的事äšg‹¹ã€?/p>

值得注意的是扩展用例的事件流往往可以也可抽象为基¼‹€ç”¨ä¾‹çš„备选流åQŒå¦‚上例中的呼叫½{‰å¾…和呼叫è{¿U»éƒ½å¯ä»¥ä½œäؓ基本通话用例的备选流而存在。但是基本通话用例已经是一个很复杂的用例了åQŒé€‰ç”¨æ‰©å±•关系ž®†å¢žå€ég¸šåŠ¡æŠ½è±¡æˆä¸ºå•ç‹¬çš„ç”¨ä¾‹å¯ä»¥é¿å…åŸºç¡€ç”¨ä¾‹˜q‡äºŽå¤æ‚åQŒåƈ且把一些可选的操作独立ž®è£…在另外的用例中ã€?/p>

4.2.3 泛化(generalization)

当多个用例共同拥有一¿Uç±»ä¼¼çš„¾l“构和行为的时候,我们可以ž®†å®ƒä»¬çš„共性抽象成为父用例åQŒå…¶ä»–çš„ç”¨ä¾‹ä½œäØ“æ³›åŒ–å…³ç³»ä¸­çš„å­ç”¨ä¾‹ã€‚åœ¨ç”¨ä¾‹çš„æ³›åŒ–å…³¾pÖM¸­åQŒå­ç”¨ä¾‹æ˜¯çˆ¶ç”¨ä¾‹çš„一¿Uç‰¹ŒDŠåŞ式,子用例ç‘ô承了父用例所有的¾l“构、行为和关系。在实际应用中很ž®‘ä‹É用泛化关¾p»ï¼Œå­ç”¨ä¾‹ä¸­çš„特ŒDŠè¡Œä¸ºéƒ½å¯ä»¥ä½œäؓ父用例中的备选流存在ã€?/p>

以下是一个用例泛化关¾pȝš„例子åQŒæ‰§è¡Œäº¤æ˜“是一¿Uäº¤æ˜“抽象,执行房äñ”äº¤æ˜“å’Œæ‰§è¡Œè¯åˆæ€º¤æ˜“都是一¿Uç‰¹ŒDŠçš„交易形式ã€?/p>

用例泛化关系中的事äšg‹¹ç¤ºä¾‹å¦‚下:



4.3 调整用例模型

用例模型建成之后åQŒæˆ‘们可以对用例模型˜q›è¡Œ‹‚€è§†ï¼Œçœ‹æ˜¯å¦å¯ä»¥è¿›ä¸€æ­¥ç®€åŒ–用例模型、提高重用程度、增加模型的可维护性。主要可以从以下‹‚€æŸ¥ç‚¹(checkpoints)入手:

  • ç”¨ä¾‹ä¹‹é—´æ˜¯å¦ç›æ€º’独立åQŸå¦‚果两个用例æ€ÀL˜¯ä»¥åŒæ ïLš„™åºåºè¢«æ¿€‹z»ï¼Œå¯èƒ½éœ€è¦å°†å®ƒä»¬åˆåƈä¸ÞZ¸€ä¸ªç”¨ä¾‹ã€?/li>
  • å¤šä¸ªç”¨ä¾‹ä¹‹é—´æ˜¯å¦æœ‰éžå¸¸ç›¸ä¼¼çš„è¡ŒäØ“æˆ–äº‹ä»¶æµåQŸå¦‚果有åQŒå¯ä»¥è€ƒè™‘ž®†å®ƒä»¬åˆòq¶äؓ一个用例ã€?/li>
  • 用例事äšg‹¹çš„一部分是否已被构徏为另一个用例?如果是,可以让该用例包含(include)另一用例ã€?/li>
  • 是否应该ž®†ä¸€ä¸ªç”¨ä¾‹çš„事äšg‹¹æ’入另一个用例的事äšg‹¹ä¸­åQŸå¦‚果是åQŒåˆ©ç”¨ä¸Žå¦ä¸€ä¸ªç”¨ä¾‹çš„æ‰©å±•关系(extend)来徏立此模型ã€?




回页�/strong>


5. ½Ž¡ç†ç”¨ä¾‹æ¨¡åž‹å¤æ‚åº?/span>

一般小型的¾pȝ»ŸåQŒå…¶ç”¨ä¾‹æ¨¡åž‹ä¸­åŒ…含的参与者和用例不会太多åQŒä¸€ä¸ªç”¨ä¾‹å›¾ž®±å¯ä»¥å®¹¾UÏx‰€æœ‰çš„å‚ä¸Žè€…ï¼Œæ‰€æœ‰çš„å‚ä¸Žè€…å’Œç”¨ä¾‹ä¹Ÿå¯ä»¥åÆˆå­˜äºŽåŒä¸€ä¸ªå±‚‹Æ¡ç»“构中。对于较复杂的大中型¾pȝ»ŸåQŒç”¨ä¾‹æ¨¡åž‹ä¸­çš„参与者和用例会大大增加,我们需要一些方法来有效地管理由于规模上升而造成的复杂度ã€?/p>

5.1 用例�/span>

åŒ?(Package)是UML中最常用的管理模型复杂度的机åˆÓž¼ŒåŒ…也是UML中语义最½Ž€å•的一¿Uæ¨¡åž‹å…ƒç´ ï¼Œå®ƒå°±æ˜¯ä¸€¿Uå®¹å™¨ï¼Œåœ¨åŒ…中可以容¾U›_…¶ä»–ä“Q意的模型元素åQˆåŒ…括其他的包)。在用例模型中,我们可以用构造型(Sterotype)<<use case>>来扩展标准UML包的语义åQŒè¿™¿Uæ–°çš„包叫作用例åŒ?Use Case Package)åQŒç”¨äºŽåˆ†¾cȝ®¡ç†ç”¨ä¾‹æ¨¡åž‹ä¸­çš„æ¨¡åž‹å…ƒç´ ã€?/p>

我们可以æ ÒŽ®å‚与者和用例的特性来对它们进行分¾c»ï¼Œåˆ†åˆ«¾|®äºŽä¸åŒçš„用例包½Ž¡ç†ä¹‹ä¸‹ã€‚例如对于一个大型的企业½Ž¡ç†ä¿¡æ¯¾pȝ»ŸåQŒæˆ‘们可以根据参与者和用例的内容将它们分别归于人力资源、胦务、采购、销售、客务服务这些用例包之下。这æ ähˆ‘ä»¬å°†æ•´ä¸ªç”¨ä¾‹æ¨¡åž‹åˆ’åˆ†æˆäØ“ä¸¤ä¸ªå±‚æ¬¡åQŒåœ¨½W¬ä¸€å±‚次我们看到的是¾pȝ»ŸåŠŸèƒ½æ€Õd…±åˆ†äؓ五部分,在第二层‹Æ¡æˆ‘们可以分别看到每一用例包内部的参与者和用例ã€?/p>

一个用例模型需要有多少个用例包取决你想怎么æ äh¥½Ž¡ç†ç”¨ä¾‹æ¨¡åž‹çš„复杂度åQˆåŒ…括参与者和用例的个敎ͼŒä»¥åŠå®ƒä»¬ä¹‹é—´çš„相互关¾p»ï¼‰ã€‚UML中的包其实就¾cÖM¼¼äºŽæ–‡ä»¶ç³»¾lŸä¸­çš„目录,文äšg数量ž®‘的时候不需要额外的目录åQŒæ–‡ä»¶æ•°é‡ä¸€å¤šå°±éœ€è¦æœ‰å¤šä¸ªç›®å½•来分¾cȝ®¡ç†ï¼ŒåŒæ ·ä¸€¾l„文件不同的äºÞZ¼šåˆ›å¾ä¸åŒçš„目录结构来˜q›è¡Œ½Ž¡ç†åQŒå…³é”®æ˜¯è¦ä¿è¯åœ¨ç›®å½•¾l“构下每一个文仉™ƒ½è¦æ˜“于访问。同æ ïLš„道理存在于用例徏模之中,如何创徏用例包以及用例包的个数取决于不同的系¾lŸå’Œ¾pȝ»Ÿåˆ†æžå‘˜ï¼Œä½†è¦ä¿è¯æ•´ä¸ªç”¨ä¾‹æ¨¡åž‹æ˜“于理解ã€?/p>

5.2 用例的粒�/span>

我的¾pȝ»Ÿéœ€è¦æœ‰å¤šå°‘个用例?˜q™æ˜¯å¾ˆå¤šäººåœ¨ç”¨ä¾‹å»ºæ¨¡æ—¶ä¼šäº§ç”Ÿçš„疑惑。描˜q°åŒä¸€ä¸ªç³»¾lŸï¼Œä¸åŒçš„äh会äñ”生不同的用例模型。例如对于各¿Uç³»¾lŸä¸­å¸¸è§çš?¾l´æŠ¤ç”¨æˆ·"用例åQŒå®ƒé‡Œé¢åŒ…含了添加用戗÷€ä¿®æ”¹ç”¨æˆ·ä¿¡æ¯ã€åˆ é™¤ç”¨æˆïL­‰æ“ä½œåQŒè¿™äº›æ“ä½œåœ¨è¯¥ç”¨ä¾‹çš„事äšg‹¹å¯ä»¥è¡¨˜q°æˆä¸ºåŸºæœ¬æµçš„子事äšg‹¹?subflow)ã€?/p>

¾l´æŠ¤ç”¨æˆ·-基本事äšg‹¹?/p>

该基本流ç”׃¸‰ä¸ªå­äº‹äšg‹¹æž„成:

1) æ·ÕdŠ ç”¨æˆ·å­äº‹ä»¶æµ

2) 修改用户 子事件流

3) 删除用户子事件流

但是你也可以æ ÒŽ®è¯¥ç”¨ä¾‹ä¸­çš„具体操作把它抽象成ä¸ÞZ¸‰ä¸ªç”¨ä¾‹ï¼Œå®ƒæ‰€è¡¨ç¤ºçš„ç³»¾lŸéœ€æ±‚和单个用例的模型是完全一æ ïLš„ã€?/p>

应该如何¼‹®å®šç”¨ä¾‹çš„粒度呢åQŸåœ¨ä¸€‹Æ¡æŠ€æœ¯ç ”讨会上,有ähé—®è“vIvar Jacoboson博士åQŒä¸€ä¸ªç³»¾lŸéœ€è¦æœ‰å¤šå°‘个用例?大师的回½{”是20个,当然他的意思是最好将用例模型的规模控制在几十个用例左叻I¼Œ˜q™æ ·æ¯”较å®ÒŽ˜“来管理用例模型的复杂度。在用例个数大致¼‹®å®šçš„æ¡ä»¶ä¸‹åQŒæˆ‘们就很容易来¼‹®å®šç”¨ä¾‹¾_’度的大ž®ã€‚对于较复杂的系¾lŸï¼Œæˆ‘们需要控制用例模型一¾U§çš„复杂度,所以可以将复杂度适当地移往每一个用例的内部åQŒä¹Ÿž®±æ˜¯è®©ä¸€ä¸ªç”¨ä¾‹åŒ…含较多的需求信息量。对于比较简单的¾pȝ»ŸåQŒæˆ‘们则可以ž®†å¤æ‚度适度地曝露在模型一¾U§ï¼Œä¹Ÿå°±æ˜¯æˆ‘ä»¬å¯ä»¥å°†è¾ƒå¤æ‚çš„ç”¨ä¾‹åˆ†è§£æˆäØ“å¤šä¸ªç”¨ä¾‹ã€?/p>

用例的粒度不但决定了用例模型¾U§çš„复杂度,而且也决定了每一个用例内部的复杂度。我们应该根据每个系¾lŸçš„具体情况åQŒå› æ—¶å› å®œåœ°æ¥æŠŠæ¡å„个层‹Æ¡çš„复杂度,在尽可能保证整个用例模型的易理解性前提下军_®šç”¨ä¾‹çš„大ž®å’Œæ•°ç›®ã€?/p>

5.3 用例�/span>

用例囄¡š„主要作用是描˜q°å‚与者和用例之间的关¾p»ï¼Œ½Ž€å•çš„¾pȝ»Ÿä¸­åªéœ€è¦æœ‰ä¸€ä¸ªç”¨ä¾‹å›¾ž®±å¯ä»¥æŠŠæ‰€æœ‰çš„关系都描˜q°æ¸…楚。复杂的¾pȝ»Ÿä¸­å¯ä»¥æœ‰å¤šä¸ªç”¨ä¾‹å›¾ï¼Œä¾‹å¦‚每个用例包都可以有一个独立的用例图来描述该用例包中所有的参与者和用例的关¾p…R€?/p>

在一个用例模型中åQŒå¦‚果参与者和用例之间存在着多对多的关系åQŒåƈ且他们之间的关系比较复杂åQŒå¦‚果在同一个用例图中表˜q°æ‰€æœ‰çš„参与者和用例ž®±æ˜¾å¾—不够清晎ͼŒ˜q™æ—¶æˆ‘们可创建多个用例图来分别表½Cºå„¿Uå…³¾p…R€?/p>

如果惌™¦å¼ø™°ƒæŸä¸€ä¸ªå‚与者和多个用例的关¾p»ï¼Œä½ å°±å¯ä»¥ä»¥è¯¥å‚ä¸Žè€…äØ“ä¸­å¿ƒåQŒç”¨ä¸€ä¸ªç”¨ä¾‹å›¾è¡¨è¿°å‡ø™¯¥å‚与者和多个用例之间的关¾p…R€‚在˜q™ä¸ªç”¨ä¾‹å›¾ä¸­åQŒæˆ‘们强调的是该参与者会使用¾pȝ»Ÿæ‰€æä¾›çš„哪些服务ã€?/p>

如果惌™¦å¼ø™°ƒæŸä¸€ä¸ªç”¨ä¾‹å’Œå¤šä¸ªå‚与者之间的关系åQŒä½ ž®±å¯ä»¥ä»¥è¯¥ç”¨ä¾‹äؓ中心åQŒç”¨ä¸€ä¸ªç”¨ä¾‹å›¾è¡¨è¿°å‡ø™¯¥ç”¨ä¾‹å’Œå¤šä¸ªå‚与者之间的关系。在˜q™ä¸ªç”¨ä¾‹å›¾ä¸­åQŒæˆ‘们强调的是该用例会涉及到哪些参与者,或者说该用例所表示的系¾lŸæœåŠ¡æœ‰å“ªäº›ä½¿ç”¨è€…ã€?/p>

æ€ÖM¹‹åœ¨ç”¨ä¾‹å¾æ¨¡è¿‡½E‹ä¸­åQŒä½ å¯ä»¥æ ÒŽ®è‡ªå·±çš„需要创å»ÞZ“Q意多个用例图åQŒç”¨ä¸åŒçš„ç”¨ä¾‹æ¥å¼ø™°ƒå‚与者和用例之间不同的关¾p…R€‚但是最重要的是要考虑整个用例模型的可理解性,如果可以用一个用例图把意思表˜q°æ¸…楚,ž®×ƒ¸è¦å†ç”¨ç¬¬äºŒä¸ªåQŒå› ä¸ø™¶Šæ˜¯ç®€‹zçš„æ¨¡åž‹­‘Šæ˜“于理解ã€?/p>

参考资�

  • 样例代码



  • Jeffrey Friedl, Mastering Regular Expressions, O'Reilly

  • Mendel Cooper, Advanced Bash-Scripting Guide

  • Michael Jang, Mastering Redhat 9


关于作�/span>

 

傅纯一åQŒIBM中国有限公司软äšg部Rational中国区技术销售经ç?/p>



]]>
设计模式之Prototype(原型)http://www.aygfsteel.com/hulizhong/archive/2009/03/09/258563.html二胡二胡Mon, 09 Mar 2009 03:00:00 GMThttp://www.aygfsteel.com/hulizhong/archive/2009/03/09/258563.htmlhttp://www.aygfsteel.com/hulizhong/comments/258563.htmlhttp://www.aygfsteel.com/hulizhong/archive/2009/03/09/258563.html#Feedback0http://www.aygfsteel.com/hulizhong/comments/commentRss/258563.htmlhttp://www.aygfsteel.com/hulizhong/services/trackbacks/258563.html

原型模式定义:
用原型实例指定创建对象的¿Uç±»,òq¶ä¸”通过拯‚´˜q™äº›åŽŸåž‹åˆ›å¾æ–°çš„å¯¹è±¡.

Prototype模式允许一个对象再创徏另外一个可定制的对象,æ ÒŽœ¬æ— éœ€çŸ¥é“ä»ÖM½•如何创徏的细èŠ?工作原理æ˜?通过ž®†ä¸€ä¸ªåŽŸåž‹å¯¹è±¡ä¼ ¾l™é‚£ä¸ªè¦å‘动创徏的对象,˜q™ä¸ªè¦å‘动创建的对象通过è¯äh±‚原型对象拯‚´å®ƒä»¬è‡ªå·±æ¥å®žæ–½åˆ›å»ºã€?/p>

如何使用?
因䨓Java中的提供clone()æ–ÒŽ³•来实现对象的克隆,所以Prototype模式实现一下子变得很简å?

ä»¥å‹ºå­äØ“ä¾‹ï¼š

public abstract class AbstractSpoon implements Cloneable
{
  String spoonName;

  public void setSpoonName(String spoonName) {this.spoonName = spoonName;}
  public String getSpoonName() {return this.spoonName;}

  public Object clone()
  {
    Object object = null;
    try {
      object = super.clone();
    } catch (CloneNotSupportedException exception) {
      System.err.println("AbstractSpoon is not Cloneable");
    }
    return object;
  }
}

有个具体实现(ConcretePrototype):

public class SoupSpoon extends AbstractSpoon
{
  public SoupSpoon()
  {
    setSpoonName("Soup Spoon");
  }
}

 

调用Prototype模式很简�

AbstractSpoon spoon = new SoupSpoon();
AbstractSpoon spoon2 = spoon.clone();

当然也可以结合工厂模式来创徏AbstractSpoon实例�/p>

在Java中Prototype模式变成clone()æ–ÒŽ³•çš„ä‹É用,ç”׃ºŽJava的纯‹zçš„面向对象ç‰ÒŽ€§ï¼Œä½¿å¾—在Java中ä‹É用设计模式变得很自然åQŒä¸¤è€…å·²¾lå‡ ä¹Žæ˜¯‹¹‘然一体了。这反映在很多模式上åQŒå¦‚Interator遍历模式ã€?/p>

]]>
设计模式之Templatehttp://www.aygfsteel.com/hulizhong/archive/2009/03/09/258562.html二胡二胡Mon, 09 Mar 2009 02:55:00 GMThttp://www.aygfsteel.com/hulizhong/archive/2009/03/09/258562.htmlhttp://www.aygfsteel.com/hulizhong/comments/258562.htmlhttp://www.aygfsteel.com/hulizhong/archive/2009/03/09/258562.html#Feedback0http://www.aygfsteel.com/hulizhong/comments/commentRss/258562.htmlhttp://www.aygfsteel.com/hulizhong/services/trackbacks/258562.html

Template模板模式定义:
定义一个操作中½Ž—法的骨æž?ž®†ä¸€äº›æ­¥éª¤çš„æ‰§è¡Œå»¶è¿Ÿåˆ°å…¶å­ç±»ä¸?

使用Java的抽象类æ—Óž¼Œž®Þq»å¸æ€¼šä½¿ç”¨åˆ°Template模式,å› æ­¤Template模式使用很普é?而且很容易理解和使用ã€?/p>

 

public abstract class Benchmark
{
  /**
  * 下面操作是我们希望在子类中完�br />   */
  public abstract void benchmark();

  /**
  * 重复执行benchmark‹Æ¡æ•°
  */
  public final long repeat (int count) {
    if (count <= 0)
      return 0;
    else {
      long startTime = System.currentTimeMillis();

    for (int i = 0; i < count; i++)
      benchmark();

    long stopTime = System.currentTimeMillis();
    return stopTime - startTime;
  }
}
}

在上例中,我们希望重复执行benchmark()操作,但是对benchmark()的具体内å®Ò޲¡æœ‰è¯´æ˜?而是延迟到其子类中描˜q?

public class MethodBenchmark extends Benchmark
{
  /**
  * 真正定义benchmark内容
  */
  public void benchmark() {

    for (int i = 0; i < Integer.MAX_VALUE; i++){
      System.out.printtln("i="+i);    
    }
  }
}

è‡Ïx­¤,Template模式已经完成,是不是很½Ž€å?

我们¿U°repeatæ–ÒŽ³•为模板方法, 它其中的benchmark()实现被åšg˜qŸåˆ°å­ç±»MethodBenchmark中实çŽîCº†åQ?/p>

看看如何使用:

Benchmark operation = new MethodBenchmark();
long duration = operation.repeat(Integer.parseInt(args[0].trim()));
System.out.println("The operation took " + duration + " milliseconds");

 

也许你以前还疑惑抽象¾cÀLœ‰ä»€ä¹ˆç”¨,现在你应该彻底明白了å? 至于˜q™æ ·åšçš„好处,很显然啊,扩展性强,以后Benchmark内容变化,我只要再做一个ç‘ô承子¾cÕd°±å¯ä»¥,不必修改其他应用代码.



]]>
ž®è°ˆ¾cȝš„å…Œ™”和依èµ?/title><link>http://www.aygfsteel.com/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.aygfsteel.com/hulizhong/archive/2009/03/06/258156.html</guid><wfw:comment>http://www.aygfsteel.com/hulizhong/comments/258156.html</wfw:comment><comments>http://www.aygfsteel.com/hulizhong/archive/2009/03/06/258156.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/hulizhong/comments/commentRss/258156.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/hulizhong/services/trackbacks/258156.html</trackback:ping><description><![CDATA[åQ’者的概念上的不同åQŒç½‘上有很多文章åQŽæˆ‘从代码实çŽîC¸Šè¯´è¯´åQ’者的不同<br />   兌™”åQšå¦‚果A¾cÈš„æœ‰ä¸ªå±žæ€§æ˜¯åQ¢ç±»åž‹ï¼Œé‚£ä¹ˆåQ¡å’ŒåQ¢å°±æ˜¯å…³è”å…³¾p»ï¼ˆå½“ç„¶å…Œ™”也分了几¿Uï¼šå•向兌™”åQŒåŒå‘关联)<br />   依赖åQšå¦‚果A¾cÈš„æ–ÒŽ³•的参数或æ–ÒŽ³•里的局部变量引用了åQ¢ç±»åQŒåˆ™æ˜¯ï¼¡ä¾èµ–åQ?br />   <br />   不对地方åQŒå¤§å®¶è¯´è¯ß_¼<img src ="http://www.aygfsteel.com/hulizhong/aggbug/258156.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/hulizhong/" target="_blank">二胡</a> 2009-03-06 11:25 <a href="http://www.aygfsteel.com/hulizhong/archive/2009/03/06/258156.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>¾cȝš„¾l„合和类的聚合的区别http://www.aygfsteel.com/hulizhong/archive/2009/03/06/258150.html二胡二胡Fri, 06 Mar 2009 03:07:00 GMThttp://www.aygfsteel.com/hulizhong/archive/2009/03/06/258150.htmlhttp://www.aygfsteel.com/hulizhong/comments/258150.htmlhttp://www.aygfsteel.com/hulizhong/archive/2009/03/06/258150.html#Feedback0http://www.aygfsteel.com/hulizhong/comments/commentRss/258150.htmlhttp://www.aygfsteel.com/hulizhong/services/trackbacks/258150.html ¾l„合: 被拥有者是拥有者的一个组成部åˆ?被拥有者的生命周期和拥有者的有强相关关系.也就是说当拥有者生命周期结束的时å€?被拥有者也消亡äº?常用于黑色实心菱形表½C?
      例如:人死äº?毛发也不存在äº?
聚合:表示事物的整ä½?部分关系的较弱情å†?常用于空心实心菱形表½C?br />

      个ähè®¤äØ“:做设计的时å€?不要专注¾l†èŠ‚.呵呵,不知道观点对å?

]]>
Ö÷Õ¾Ö©Öë³ØÄ£°å£º ÄÏÑôÊÐ| ¼ªÂ¡ÏØ| ÁÙ²×ÊÐ| ƽÑôÏØ| Õò°²ÏØ| ¸ÄÔòÏØ| ɽ¶«Ê¡| ½¨Æ½ÏØ| Ö麣ÊÐ| ¶þÊÖ·¿| ÃñºÍ| ·ïÌ¨ÏØ| ³¤ÄþÏØ| Õò°ÍÏØ| ¶«¸ÛÊÐ| ÐìÎÅÏØ| ¡×ÓÏØ| Õê·áÏØ| º£ÄþÊÐ| ÄϰÄÏØ| ÓÀ¿µÊÐ| ·ïÏèÏØ| µ±ÑôÊÐ| ÔÞ»ÊÏØ| ºìÇÅÇø| ·î»¯ÊÐ| ÅÊÖ¦»¨ÊÐ| ÃàÑôÊÐ| ½ú½­ÊÐ| ÉäÑôÏØ| ×ó¹±ÏØ| ¿ÂÆºÏØ| Àè´¨ÏØ| Äϰ²ÊÐ| Т²ýÏØ| ÏɾÓÏØ| ÕØ¶«ÊÐ| èï³ÇÏØ| ·ïɽÊÐ| ÎÌÔ´ÏØ| ԭƽÊÐ|