﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-asklxf-文章分类-OO &amp; Patterns</title><link>http://www.blogjava.net/asklxf/category/5518.html</link><description>A java developer's notebook.</description><language>zh-cn</language><lastBuildDate>Tue, 27 Feb 2007 15:00:08 GMT</lastBuildDate><pubDate>Tue, 27 Feb 2007 15:00:08 GMT</pubDate><ttl>60</ttl><item><title>状态模式之星际应用</title><link>http://www.blogjava.net/asklxf/articles/22198.html</link><dc:creator>Xuefeng's Weblog</dc:creator><author>Xuefeng's Weblog</author><pubDate>Fri, 02 Dec 2005 02:32:00 GMT</pubDate><guid>http://www.blogjava.net/asklxf/articles/22198.html</guid><wfw:comment>http://www.blogjava.net/asklxf/comments/22198.html</wfw:comment><comments>http://www.blogjava.net/asklxf/articles/22198.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/asklxf/comments/commentRss/22198.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/asklxf/services/trackbacks/22198.html</trackback:ping><description><![CDATA[一个对象有多种状态，在不同的状态下，同一种方法有不同的行为。如果用swich-case语句，将有大量的条件分支和逻辑代码混在一起。状态模式将每个状态封装到一个独立的类中，利用多态性使得不同状态下同一种方法表现不同的行为。<BR><BR>状态模式的UML图如下：<BR><BR><IMG onmouseover="this.style.cursor='hand';" style="CURSOR: hand" onclick=window.open(this.src); height=190 alt=按此在新窗口打开图片 src="http://www.crackj2ee.com/Article/UploadFiles/200505/20050505153407754.gif" width=472 onload=javascript:DrawImage(this); border=0><BR><BR>星际中人族的机枪兵Marine有两种状态：普通状态和打了兴奋针后的状态，两种状态下机枪兵的开枪频率是不同的，我们用状态模式来实现机枪兵的fire()方法。<BR><BR>首先定义抽象状态State接口，这个接口指定了机枪兵的fire行为：<BR><BR><FONT face=Courier&nbsp;New><FONT color=teal>public&nbsp;interface&nbsp;State&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;fire();<BR>}</FONT></FONT><BR><BR>State接口有一个fire()方法，我们实现两个子类NormalState和ExcitedState，分别表示普通状态和打了兴奋针后的状态，并实现具体的fire方法：<BR><BR><FONT face=Courier&nbsp;New><FONT color=teal>public&nbsp;class&nbsp;NormalState&nbsp;implements&nbsp;State&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;fire()&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("普通状态每秒开枪1次。");<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>}<BR><BR>public&nbsp;class&nbsp;ExcitedState&nbsp;implements&nbsp;State&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;fire()&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("兴奋状态每秒开枪2次。");<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>}</FONT></FONT><BR><BR>最后，定义机枪兵类Marine，每个Marine的实例代表一个机枪兵：<BR><BR><FONT face=Courier&nbsp;New><FONT color=teal>public&nbsp;class&nbsp;Marine&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;保持一个状态类的实例：<BR>&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;State&nbsp;state&nbsp;=&nbsp;new&nbsp;NormalState();<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;为机枪兵设置状态：<BR>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;setState(State&nbsp;state)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.state&nbsp;=&nbsp;state;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;fire()方法，实际调用的是state变量的fire()方法：<BR>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;fire()&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;state.fire();<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>}</FONT></FONT><BR><BR>最后我们看看如何在客户端控制一个机枪兵的状态：<BR><BR><FONT face=Courier&nbsp;New><FONT color=teal>public&nbsp;static&nbsp;void&nbsp;main(String[]&nbsp;args)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;创建一个机枪兵的实例：<BR>&nbsp;&nbsp;&nbsp;&nbsp;Marine&nbsp;marine&nbsp;=&nbsp;new&nbsp;Marine();<BR>&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;调用fire()方法：<BR>&nbsp;&nbsp;&nbsp;&nbsp;marine.fire();<BR>&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;设置为兴奋状态：<BR>&nbsp;&nbsp;&nbsp;&nbsp;marine.setState(new&nbsp;ExcitedState());<BR>&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;再调用fire()方法：<BR>&nbsp;&nbsp;&nbsp;&nbsp;marine.fire();<BR>}</FONT></FONT><BR><BR>对同一个Marine对象调用两次fire()方法，屏幕输出为：<BR><BR><FONT face=Courier&nbsp;New><FONT color=teal>普通状态每秒开枪1次。<BR>兴奋状态每秒开枪2次。</FONT></FONT><BR><BR>可见机枪兵在两种状态下的同一个fire()方法有不同的行为。<BR><BR>使用状态模式的好处是每个状态被封装到一个独立的类中，这些类可以独立变化，而主对象中没有繁琐的swich-case语句，并且添加新的状态非常容易，只需要从State派生一个新类即可。<BR><BR><FONT color=maroon>（参考：Design&nbsp;Patterns）</FONT><img src ="http://www.blogjava.net/asklxf/aggbug/22198.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/asklxf/" target="_blank">Xuefeng's Weblog</a> 2005-12-02 10:32 <a href="http://www.blogjava.net/asklxf/articles/22198.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>