﻿<?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>C++博客-mooyee's blog-随笔分类-UML,RUP,设计模式</title><link>http://www.cppblog.com/mooyee/category/1119.html</link><description /><language>zh-cn</language><lastBuildDate>Sat, 24 May 2008 01:01:58 GMT</lastBuildDate><pubDate>Sat, 24 May 2008 01:01:58 GMT</pubDate><ttl>60</ttl><item><title>从实例开始谈状态图的使用</title><link>http://www.cppblog.com/mooyee/archive/2006/03/15/4205.html</link><dc:creator>stone</dc:creator><author>stone</author><pubDate>Wed, 15 Mar 2006 09:23:00 GMT</pubDate><guid>http://www.cppblog.com/mooyee/archive/2006/03/15/4205.html</guid><wfw:comment>http://www.cppblog.com/mooyee/comments/4205.html</wfw:comment><comments>http://www.cppblog.com/mooyee/archive/2006/03/15/4205.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mooyee/comments/commentRss/4205.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mooyee/services/trackbacks/4205.html</trackback:ping><description><![CDATA[<H1 style="MARGIN: 17pt 0cm 16.5pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">从实例开始谈状态图的使用</SPAN></H1>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><SPAN style="mso-tab-count: 14">&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;&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;2005119@gmail.com</SPAN></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><SPAN style="mso-spacerun: yes">&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;&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; </SPAN>v1.0 <?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" /><st1:chsdate w:st="on" Year="2006" Month="3" Day="15" IsLunarDate="False" IsROCDate="False">2006-03-15</st1:chsdate></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">摘要：在对“靓号租用”项目的重构中，我通过状态图很好的理解了业务逻辑。由此进一步归纳了状态图在开发过程中的使用提示和技巧。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">关键词：</SPAN><SPAN lang=EN-US>UML</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，状态图，重构</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">读者水平：初级</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P>
<H2 style="MARGIN: 13pt 0cm"><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">引言</SPAN></H2>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 15.75pt; mso-char-indent-count: 1.5"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">“靓号租用”是原无线技术部门开发</SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 新宋体; mso-font-kerning: 0pt; mso-hansi-font-family: 'Times New Roman'">GLSMRPIDService</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 新宋体; mso-font-kerning: 0pt; mso-hansi-font-family: 'Times New Roman'">中的一个部分，由于这部分存在已的功能缺陷，需要对之进行适当的修改，通过这种方式来使功能得到完善并使版本得到演进。我先给出当前需求，对对象“靓号”的状态图。<SPAN lang=EN-US><o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 新宋体; mso-font-kerning: 0pt; mso-hansi-font-family: 'Times New Roman'"><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 15.75pt; mso-char-indent-count: 1.5"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">按图说图图（</SPAN><SPAN lang=EN-US>1</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）描述了对象“靓号”在其生命期中的几个状态，“靓号”能被锁定，被锁定的“靓号”不能被其它用户再锁定。被锁定的靓号如果在</SPAN><SPAN lang=EN-US>15</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">分钟内没被用户租用，则还回到初始状态，可以再被（其他）用户锁定。被锁定的“靓号”可以被租用，租用到期后能被系统预留（即为先前的用户保护起来），预留一个月后如用户未续租，则此“靓号”可以被其他人锁定或租用。在租用状态下的“靓号”，如果被同一用户累积租用超过半年，则可以买断。被买断后，此“靓号”变成普通号。<BR></SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 新宋体; mso-font-kerning: 0pt; mso-hansi-font-family: 'Times New Roman'"><o:p></o:p></SPAN></P>
<H2 style="MARGIN: 13pt 0cm"><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial"><IMG alt="" hspace=0 src="C:\Documents and Settings\jiangtao\桌面\dgm4417ba24001f.png" align=baseline border=0></SPAN></H2>
<H2 style="MARGIN: 13pt 0cm"><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">概念</SPAN></H2>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 26.25pt; mso-char-indent-count: 2.5"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">很遗憾，原设计由于所面对的问题领域规模小，所以并没有采用</SPAN><SPAN lang=EN-US>OOD/OOP</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的方式，所以看不到<B style="mso-bidi-font-weight: normal">类</B></SPAN><SPAN lang=EN-US><?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" /><v:shape id=_x0000_i1026 style="WIDTH: 124.5pt; HEIGHT: 30.75pt" type="#_x0000_t75"> <v:imagedata o:title="" src="file:///C:\DOCUME~1\jiangtao\LOCALS~1\Temp\msohtml1\01\clip_image003.emz"></v:imagedata></v:shape><B style="mso-bidi-font-weight: normal">CCoolIdentity</B></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这样的实体类，但由于问题领域所处理的对象即为“靓号”，因此，这里先引入这个类。这里，插入状态图使用的第一个准则：</SPAN></P>
<TABLE class=MsoTableGrid style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; MARGIN: auto auto auto 32.4pt; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none; BORDER-COLLAPSE: collapse; mso-border-alt: solid windowtext .5pt; mso-yfti-tbllook: 480; mso-padding-alt: 0cm 5.4pt 0cm 5.4pt; mso-border-insideh: .5pt solid windowtext; mso-border-insidev: .5pt solid windowtext" cellSpacing=0 cellPadding=0 border=1>
<TBODY>
<TR style="mso-yfti-irow: 0; mso-yfti-firstrow: yes; mso-yfti-lastrow: yes">
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 1pt solid; WIDTH: 393.7pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid windowtext .5pt" vAlign=top width=525>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">准则</SPAN><SPAN lang=EN-US>1: </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">状态图只对单一对象的复杂行为进行模建。这里的对象指类、角色、子系统、或组件。</SPAN></P></TD></TR></TBODY></TABLE>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">因此，状态图并不为多个对象之间的行为建模。多个对象之间的行为建模参考“活动图”，“时序图”，对象之间的关系参考“类图”，“对象图”以及参考设计模式</SPAN><SPAN lang=EN-US>(</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">设计模式通常用</SPAN><SPAN lang=EN-US>UML</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">或</SPAN><SPAN lang=EN-US>Booch</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">图表示类之间的关系</SPAN><SPAN lang=EN-US>, Booch</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是</SPAN><SPAN lang=EN-US>UML</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的前身</SPAN><SPAN lang=EN-US>)</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。现在我们给出状态图的定义。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">状态图，全称为状态机视图</SPAN><SPAN lang=EN-US>(state machine view)</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，通过对每个类的生个对象形字的生命期建模，描述了对象在时间上的动态行为。</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体">状态图</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">用于对模型元素的动态行为进行建模，更具体地说，就是对系统行为中受事件驱动的方面进行建模。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><SPAN style="mso-spacerun: yes">&nbsp;&nbsp; </SPAN></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><SPAN style="mso-spacerun: yes">&nbsp; </SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">状态图由状态组成，各状态由转移链接在一起。状态是对象执行某项活动或等待某个事件时的条件。转移是两个状态之间的关系，它由某个事件触发，然后执行特定的操作或评估并导致特定的结束状态。图</SPAN> <SPAN lang=EN-US>(2) </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">描绘了状态图的各种元素。</SPAN></P>
<TABLE class=MsoTableGrid style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none; BORDER-COLLAPSE: collapse; mso-border-alt: solid windowtext .5pt; mso-yfti-tbllook: 480; mso-padding-alt: 0cm 5.4pt 0cm 5.4pt; mso-border-insideh: .5pt solid windowtext; mso-border-insidev: .5pt solid windowtext" cellSpacing=0 cellPadding=0 border=1>
<TBODY>
<TR style="mso-yfti-irow: 0; mso-yfti-firstrow: yes; mso-yfti-lastrow: yes">
<TD style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 1pt solid; WIDTH: 426.1pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid windowtext .5pt" vAlign=top width=568>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US>图2<IMG height=278 alt=md_state1.gif src="http://www.cppblog.com/images/cppblog_com/mooyee/md_state1.gif" width=511 border=0></SPAN></P></TD></TR></TBODY></TABLE>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">态是对象执行某项活动或等待某个事件时的条件。对象可能会在有限的时间长度内保持某一状态。状态具有以下几项特征：</SPAN></P>
<DIV align=center>
<TABLE class=MsoNormalTable style="BORDER-RIGHT: gray 1pt solid; BORDER-TOP: gray 1pt solid; MARGIN: auto auto auto 37.3pt; BORDER-LEFT: gray 1pt solid; WIDTH: 429.2pt; BORDER-BOTTOM: gray 1pt solid; mso-border-alt: solid gray .75pt; mso-padding-alt: 1.5pt 1.5pt 1.5pt 1.5pt; mso-cellspacing: 0cm" cellSpacing=0 cellPadding=0 width=572 border=1>
<TBODY>
<TR style="HEIGHT: 18.75pt; mso-yfti-irow: 0; mso-yfti-firstrow: yes">
<TD style="BORDER-RIGHT: gray 1pt inset; PADDING-RIGHT: 1.5pt; BORDER-TOP: gray 1pt inset; PADDING-LEFT: 1.5pt; PADDING-BOTTOM: 1.5pt; BORDER-LEFT: gray 1pt inset; WIDTH: 140.1pt; PADDING-TOP: 1.5pt; BORDER-BOTTOM: gray 1pt inset; HEIGHT: 18.75pt; BACKGROUND-COLOR: transparent; mso-border-alt: inset gray .75pt" vAlign=top width=187>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">名称</SPAN></P></TD>
<TD style="BORDER-RIGHT: gray 1pt inset; PADDING-RIGHT: 1.5pt; BORDER-TOP: gray 1pt inset; PADDING-LEFT: 1.5pt; PADDING-BOTTOM: 1.5pt; BORDER-LEFT: gray 1pt inset; WIDTH: 289.1pt; PADDING-TOP: 1.5pt; BORDER-BOTTOM: gray 1pt inset; HEIGHT: 18.75pt; BACKGROUND-COLOR: transparent; mso-border-alt: inset gray .75pt" vAlign=top width=385>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">将一个状态与其他状态区分开来的文本字符串；状态也可能是匿名的，这表示它没有名称。</SPAN></P></TD></TR>
<TR style="HEIGHT: 18.75pt; mso-yfti-irow: 1">
<TD style="BORDER-RIGHT: gray 1pt inset; PADDING-RIGHT: 1.5pt; BORDER-TOP: gray 1pt inset; PADDING-LEFT: 1.5pt; PADDING-BOTTOM: 1.5pt; BORDER-LEFT: gray 1pt inset; WIDTH: 140.1pt; PADDING-TOP: 1.5pt; BORDER-BOTTOM: gray 1pt inset; HEIGHT: 18.75pt; BACKGROUND-COLOR: transparent; mso-border-alt: inset gray .75pt" vAlign=top width=187>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 3pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><B><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-font-kerning: 0pt; mso-bidi-font-family: Arial; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial">进入</SPAN></B><B><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; mso-bidi-font-size: 12.0pt; mso-font-kerning: 0pt">/</SPAN></B><B><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-font-kerning: 0pt; mso-bidi-font-family: Arial; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial">退出操作</SPAN></B><SPAN lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: gray 1pt inset; PADDING-RIGHT: 1.5pt; BORDER-TOP: gray 1pt inset; PADDING-LEFT: 1.5pt; PADDING-BOTTOM: 1.5pt; BORDER-LEFT: gray 1pt inset; WIDTH: 289.1pt; PADDING-TOP: 1.5pt; BORDER-BOTTOM: gray 1pt inset; HEIGHT: 18.75pt; BACKGROUND-COLOR: transparent; mso-border-alt: inset gray .75pt" vAlign=top width=385>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在进入和退出状态时所执行的操作。</SPAN></P></TD></TR>
<TR style="HEIGHT: 18.75pt; mso-yfti-irow: 2">
<TD style="BORDER-RIGHT: gray 1pt inset; PADDING-RIGHT: 1.5pt; BORDER-TOP: gray 1pt inset; PADDING-LEFT: 1.5pt; PADDING-BOTTOM: 1.5pt; BORDER-LEFT: gray 1pt inset; WIDTH: 140.1pt; PADDING-TOP: 1.5pt; BORDER-BOTTOM: gray 1pt inset; HEIGHT: 18.75pt; BACKGROUND-COLOR: transparent; mso-border-alt: inset gray .75pt" vAlign=top width=187>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 3pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><B><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-font-kerning: 0pt; mso-bidi-font-family: Arial; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial">内部转移</SPAN></B><SPAN lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: gray 1pt inset; PADDING-RIGHT: 1.5pt; BORDER-TOP: gray 1pt inset; PADDING-LEFT: 1.5pt; PADDING-BOTTOM: 1.5pt; BORDER-LEFT: gray 1pt inset; WIDTH: 289.1pt; PADDING-TOP: 1.5pt; BORDER-BOTTOM: gray 1pt inset; HEIGHT: 18.75pt; BACKGROUND-COLOR: transparent; mso-border-alt: inset gray .75pt" vAlign=top width=385>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在不使状态发生变更的情况下进行的转移。</SPAN></P></TD></TR>
<TR style="HEIGHT: 18.75pt; mso-yfti-irow: 3">
<TD style="BORDER-RIGHT: gray 1pt inset; PADDING-RIGHT: 1.5pt; BORDER-TOP: gray 1pt inset; PADDING-LEFT: 1.5pt; PADDING-BOTTOM: 1.5pt; BORDER-LEFT: gray 1pt inset; WIDTH: 140.1pt; PADDING-TOP: 1.5pt; BORDER-BOTTOM: gray 1pt inset; HEIGHT: 18.75pt; BACKGROUND-COLOR: transparent; mso-border-alt: inset gray .75pt" vAlign=top width=187>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 3pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><B><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-font-kerning: 0pt; mso-bidi-font-family: Arial; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial">子状态</SPAN></B><SPAN lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: gray 1pt inset; PADDING-RIGHT: 1.5pt; BORDER-TOP: gray 1pt inset; PADDING-LEFT: 1.5pt; PADDING-BOTTOM: 1.5pt; BORDER-LEFT: gray 1pt inset; WIDTH: 289.1pt; PADDING-TOP: 1.5pt; BORDER-BOTTOM: gray 1pt inset; HEIGHT: 18.75pt; BACKGROUND-COLOR: transparent; mso-border-alt: inset gray .75pt" vAlign=top width=385>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">状态的嵌套结构，包括不相连的（依次处于活动状态的）或并行的（同时处于活动状态的）子状态。</SPAN></P></TD></TR>
<TR style="HEIGHT: 18.75pt; mso-yfti-irow: 4; mso-yfti-lastrow: yes">
<TD style="BORDER-RIGHT: gray 1pt inset; PADDING-RIGHT: 1.5pt; BORDER-TOP: gray 1pt inset; PADDING-LEFT: 1.5pt; PADDING-BOTTOM: 1.5pt; BORDER-LEFT: gray 1pt inset; WIDTH: 140.1pt; PADDING-TOP: 1.5pt; BORDER-BOTTOM: gray 1pt inset; HEIGHT: 18.75pt; BACKGROUND-COLOR: transparent; mso-border-alt: inset gray .75pt" vAlign=top width=187>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 3pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align=left><B><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 12.0pt; mso-font-kerning: 0pt; mso-bidi-font-family: Arial; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial">延迟的事件</SPAN></B><SPAN lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p></o:p></SPAN></P></TD>
<TD style="BORDER-RIGHT: gray 1pt inset; PADDING-RIGHT: 1.5pt; BORDER-TOP: gray 1pt inset; PADDING-LEFT: 1.5pt; PADDING-BOTTOM: 1.5pt; BORDER-LEFT: gray 1pt inset; WIDTH: 289.1pt; PADDING-TOP: 1.5pt; BORDER-BOTTOM: gray 1pt inset; HEIGHT: 18.75pt; BACKGROUND-COLOR: transparent; mso-border-alt: inset gray .75pt" vAlign=top width=385>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">未在该状态中处理但被延迟处理（即列队等待由另一个状态中的对象来处理）的一系列事件。</SPAN></P></TD></TR></TBODY></TABLE></DIV>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如图</SPAN> <SPAN lang=EN-US>(2) </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">所示，可以为对象的状态图定义两种特殊的状态。初始状态指示状态图或子状态的默认起始位置。</SPAN></P>
<H2 style="MARGIN: 13pt 0cm"><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">何时需要状态图</SPAN></H2>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在实际的项目开发中，并不是对每一个类都画状态图。何时需要状态图，我们可以采用下面的原则来确定：</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">敏捷建模</SPAN><SPAN lang=EN-US>( AM) ( Ambler 2002)</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的原则－－最大化项目干系人的投资－－建议你只有当模型能够提供正面价值的时候才创建模型。</SPAN> <SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如果一个实体，比如一个类或组件，表示的行为的顺序和当前的状态无关，那么画一个</SPAN><SPAN lang=EN-US>UML</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">状态图可能是没有什么用处的。例如一个</SPAN><SPAN lang=EN-US>CLogFile</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类就很简单，表示了那些你将会在系统中记录一操作的数据，因此一个</SPAN><SPAN lang=EN-US>UML</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">状态图就没有任何相关之处。而“靓号”这类对象就经比较的复杂。</SPAN></P>
<H2 style="MARGIN: 13pt 0cm"><A name=Hints_and_Tips><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">提示与技巧</SPAN></A></H2>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 21.0pt"><SPAN lang=EN-US style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><SPAN style="mso-list: Ignore">l<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">当给定一项选择时，要使用状态图的可视语义，而不要写出详细的转移代码。例如，不要用几个信号触发一个转移，然后使用详细代码来管理以不同的方式依赖于信号的控制流。应使用由单独的信号来触发的单独转移。在隐藏了附加行为的转移代码中，要避免使用条件逻辑。</SPAN> </P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 21.0pt"><SPAN lang=EN-US style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><SPAN style="mso-list: Ignore">l<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">根据在状态期间等待的事件或正在发生的事件来命名状态。记住，状态不是“时间点”；它是状态图等待某个事件发生的时间段。例如，“</SPAN><SPAN lang=EN-US>waitingForEnd</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">”这一名称比“</SPAN><SPAN lang=EN-US>end</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">”更好；“</SPAN><SPAN lang=EN-US>timingSomeActivity</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">”比“</SPAN><SPAN lang=EN-US>timeout</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">”更好。不要让状态的名称看起来象是操作名。</SPAN> </P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 21.0pt"><SPAN lang=EN-US style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><SPAN style="mso-list: Ignore">l<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在一个状态图内唯一地命名所有状态和转移；这将便于进行源级别的调试。</SPAN> </P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 21.0pt"><SPAN lang=EN-US style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><SPAN style="mso-list: Ignore">l<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">谨慎使用状态变量；不要在创建新状态时使用它们。如果状态不多，很少带有或不带有依赖于状态的行为，并且很少有或根本没有可能与包含状态图的封装体并行或独立的行为，就可以使用状态变量。如果有复杂的、依赖于状态的潜在并行行为，或者如果必须处理的事件可能来自于包含状态图的封装体之外，则应考虑使用构件封装体。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 21.0pt"><SPAN lang=EN-US style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><SPAN style="mso-list: Ignore">l<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如果单个图中的状态超过</SPAN><SPAN lang=EN-US> 5 * 2 </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">个，就应考虑使用子状态。在这里可以应用我们的常识：在一个非常规则的模式中可以有十个状态，但如果两个状态之间具有四十个转移，显然就需要重新考虑了。务必要使状态图易于理解。</SPAN> </P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 21.0pt"><SPAN lang=EN-US style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><SPAN style="mso-list: Ignore">l<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">使用触发事件的事件和</SPAN><SPAN lang=EN-US>/</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">或在转移期间发生的事件为转移命名。选择更加易于理解的名称。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 21.0pt"><SPAN lang=EN-US style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><SPAN style="mso-list: Ignore">l<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">当您看见一个选择点时，应考虑是否可以将作出该选择的职责委托给另一个构件，以便将其作为一组将不同的信号提供给封装体遵照执行（例如，代替对消息</SPAN><SPAN lang=EN-US>-&gt;</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">数据</SPAN><SPAN lang=EN-US> &gt; x </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的选择），并考虑是否可以让发送方或另一中间主角来作出决定，然后通过在信号名称中明确显示该决定的方式发送信号（例如，使用名为</SPAN><SPAN lang=EN-US> isFull </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</SPAN><SPAN lang=EN-US> isEmpty </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的信号，而不是以值命名信号并检查消息数据）。</SPAN> </P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 21.0pt"><SPAN lang=EN-US style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><SPAN style="mso-list: Ignore">l<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">为在选择点中回答的问题指定描述性的名称，例如“</SPAN><SPAN lang=EN-US>isThereStillLife</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">”或“</SPAN><SPAN lang=EN-US>isItTimeToComplain</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">”。</SPAN> </P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 21.0pt"><SPAN lang=EN-US style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><SPAN style="mso-list: Ignore">l<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在任何给定的封装体中，尽量使选择点名称保持唯一（其原因与转移名称需保持唯一相同）。</SPAN> </P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 21.0pt"><SPAN lang=EN-US style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><SPAN style="mso-list: Ignore">l<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">转移的代码段是否太长？是否应使用函数来代替它们，是否将常用代码段记录为函数？转移应该类似于高层的伪代码，并且应当遵循与</SPAN><SPAN lang=EN-US> C++ </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">函数相同或更严格的长度规则。例如，代码超过</SPAN><SPAN lang=EN-US> 25 </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">行的转移可被认为是过长。</SPAN> </P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 21.0pt"><SPAN lang=EN-US style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><SPAN style="mso-list: Ignore">l<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">应根据函数执行的操作来命名函数。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 21.0pt"><SPAN lang=EN-US style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><SPAN style="mso-list: Ignore">l<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">要特别注意进入和退出操作：在进行更改后忘记更改相应进入和退出操作的情况尤其容易发生。</SPAN> </P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 21.0pt"><SPAN lang=EN-US style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><SPAN style="mso-list: Ignore">l<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">退出操作可用于提供安全性功能，例如，从“</SPAN><SPAN lang=EN-US>heaterOn</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">”状态中的退出操作将关闭加热器，在这里，操作被用来强制执行一个断言语句。</SPAN> </P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 21.0pt"><SPAN lang=EN-US style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><SPAN style="mso-list: Ignore">l<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">通常，除非状态图是抽象的并且将由包含元素的子类来进行改进，否则子状态应包含两个或更多个状态。</SPAN><SPAN lang=EN-US> </SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 21.0pt"><SPAN lang=EN-US style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><SPAN style="mso-list: Ignore">l<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">应该用选择点来代替操作或转移中的条件逻辑。选择点容易被看到，而代码中的条件逻辑则是不可见的，很容易被忽略。</SPAN><SPAN lang=EN-US> </SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 21.0pt"><SPAN lang=EN-US style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><SPAN style="mso-list: Ignore">l<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">避免使用警戒条件。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; mso-list: l0 level2 lfo1; tab-stops: list 42.0pt"><SPAN lang=EN-US style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><SPAN style="mso-list: Ignore">n<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如果事件触发了几个转移，将无法控制首先对哪个警戒条件求值。这会产生无法预料的结果。</SPAN><SPAN lang=EN-US> </SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; mso-list: l0 level2 lfo1; tab-stops: list 42.0pt"><SPAN lang=EN-US style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><SPAN style="mso-list: Ignore">n<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">可能有多个警戒条件为“</SPAN><SPAN lang=EN-US>True</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">”，但随后只能有一个转移。所选择的路径是无法预料的。</SPAN><SPAN lang=EN-US> </SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; mso-list: l0 level2 lfo1; tab-stops: list 42.0pt"><SPAN lang=EN-US style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><SPAN style="mso-list: Ignore">n<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">警戒条件是不可见的；要“看见”它们的出现更是困难。</SPAN><SPAN lang=EN-US> </SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; mso-list: l0 level2 lfo1; tab-stops: list 42.0pt"><SPAN lang=EN-US style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><SPAN style="mso-list: Ignore">n<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">避免使用类似流程图的状态图。</SPAN><SPAN lang=EN-US> </SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 63pt; TEXT-INDENT: -21pt; mso-list: l0 level3 lfo1; tab-stops: list 63.0pt"><SPAN lang=EN-US style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><SPAN style="mso-list: Ignore">u<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这可能表示您试图对并不实际存在的抽象概念进行建模，例如：</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 63pt; TEXT-INDENT: -21pt; mso-list: l0 level3 lfo1; tab-stops: list 63.0pt"><SPAN lang=EN-US style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><SPAN style="mso-list: Ignore">u<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">使用一个封装体来对最适合于数据类的行为进行建模，或</SPAN><SPAN lang=EN-US> </SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; mso-list: l0 level2 lfo1; tab-stops: list 42.0pt"><SPAN lang=EN-US style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><SPAN style="mso-list: Ignore">n<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">通过使用紧密耦合的数据类和封装体类来对数据类建模（例如，数据类用于向四周传递类型信息，但封装体类包含了应与数据类相关联的大部分数据）。</SPAN><SPAN lang=EN-US> </SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 63pt; TEXT-INDENT: -21pt; mso-list: l0 level3 lfo1; tab-stops: list 63.0pt"><SPAN lang=EN-US style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><SPAN style="mso-list: Ignore">u<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">状态图的这种错误用法可以通过以下故障现象来识别：</SPAN><SPAN lang=EN-US> </SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 63pt; TEXT-INDENT: -21pt; mso-list: l0 level3 lfo1; tab-stops: list 63.0pt"><SPAN lang=EN-US style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><SPAN style="mso-list: Ignore">u<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">被发送给“自己”的消息，主要是为了重复使用代码</SPAN><SPAN lang=EN-US> </SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 63pt; TEXT-INDENT: -21pt; mso-list: l0 level3 lfo1; tab-stops: list 63.0pt"><SPAN lang=EN-US style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><SPAN style="mso-list: Ignore">u<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">几乎没有状态，但有很多选择点</SPAN><SPAN lang=EN-US> </SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 63pt; TEXT-INDENT: -21pt; mso-list: l0 level3 lfo1; tab-stops: list 63.0pt"><SPAN lang=EN-US style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><SPAN style="mso-list: Ignore">u<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在某些情况下没有循环的状态图。在流程控制应用程序中，或者在试图控制一个事件序列时，这样的状态图是有效的；如果它们在分析过程中出现，则表示状态图已退化为流程图。</SPAN><SPAN lang=EN-US> </SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; mso-list: l0 level2 lfo1; tab-stops: list 42.0pt"><SPAN lang=EN-US style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><SPAN style="mso-list: Ignore">n<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">当发现问题时，应采取以下措施：</SPAN><SPAN lang=EN-US> </SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 63pt; TEXT-INDENT: -21pt; mso-list: l0 level3 lfo1; tab-stops: list 63.0pt"><SPAN lang=EN-US style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><SPAN style="mso-list: Ignore">u<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">考虑将封装体分解为职责更明确的小单元，</SPAN><SPAN lang=EN-US> </SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 63pt; TEXT-INDENT: -21pt; mso-list: l0 level3 lfo1; tab-stops: list 63.0pt"><SPAN lang=EN-US style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><SPAN style="mso-list: Ignore">u<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">将更多的行为转移到与有问题的封装体相关联的数据类中。</SPAN><SPAN lang=EN-US> </SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 63pt; TEXT-INDENT: -21pt; mso-list: l0 level3 lfo1; tab-stops: list 63.0pt"><SPAN lang=EN-US style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><SPAN style="mso-list: Ignore">u<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">将更多的行为转移到封装体类函数中。</SPAN> </P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 63pt; TEXT-INDENT: -21pt; mso-list: l0 level3 lfo1; tab-stops: list 63.0pt"><SPAN lang=EN-US style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><SPAN style="mso-list: Ignore">u<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">制作更有意义的信号，以避免对数据的依赖。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 21.0pt"><SPAN lang=EN-US style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><SPAN style="mso-list: Ignore">l<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">避免</SPAN><SPAN lang=EN-US>"</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">黑洞</SPAN><SPAN lang=EN-US>"</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">状态。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; mso-list: l0 level2 lfo1; tab-stops: list 42.0pt"><SPAN lang=EN-US style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><SPAN style="mso-list: Ignore">n<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">黑洞状态是那种只有变换进来但没有任何变换发出的状态，这种情况要么由于该状态是一个最终状态，要么就是你已经错过了一个或多个变换变换。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 21.0pt"><SPAN lang=EN-US style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><SPAN style="mso-list: Ignore">l<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">避免</SPAN><SPAN lang=EN-US>"</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">奇迹</SPAN><SPAN lang=EN-US>"</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">状态。</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; mso-list: l0 level2 lfo1; tab-stops: list 42.0pt"><SPAN lang=EN-US style="FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><SPAN style="mso-list: Ignore">n<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">奇迹状态是那种只有变换发出但没有任何变换进来的状态，这种情况要么由于该状态是一个起点，要么就是你已经错过了一个或多个变换变换。</SPAN></P>
<H2 style="MARGIN: 13pt 0cm"><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">参考文献</SPAN></H2>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">《</SPAN><SPAN lang=EN-US>UML</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">用户手册》</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">“</SPAN><SPAN lang=EN-US>Rational Unified Process</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">”</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">其它网络资源</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p>&nbsp;</o:p></SPAN></P><img src ="http://www.cppblog.com/mooyee/aggbug/4205.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mooyee/" target="_blank">stone</a> 2006-03-15 17:23 <a href="http://www.cppblog.com/mooyee/archive/2006/03/15/4205.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>