📄 +
字号:
<html><!-- #BeginTemplate "/Templates/module.dwt" --><!-- DW6 -->
<head>
<!-- #BeginEditable "doctitle" -->
<title> 设计模式之State 状态模式</title>
<!-- #EndEditable -->
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<link href="../jdon.css" rel="stylesheet" type="text/css">
<link rel="shortcut icon" href="http://www.jdon.com/favicon.ico">
<meta http-equiv="refresh" content="1200">
</head>
<body bgcolor="#014E82" text="#000000">
<table width="750" border="0" align="center" cellpadding="0" cellspacing="0">
<tr>
<td width="129" rowspan="3" align="center" valign="bottom" bgcolor="#FFFFFF">
<table width="100%" border="0" cellpadding="0" cellspacing="0" >
<tr>
<td align="center" >
<img src="http://www.jdon.com/images/jdon.gif" width="120" height="60"></td>
</tr>
<tr>
<td height="9"></td>
</tr>
</table>
</td>
<td valign="bottom" >
<table cellpadding="0" cellspacing="0" height="100%" width="100%" >
<tr bgcolor="#CAC9BB">
<td height="70" align="right" valign="bottom" bgcolor="#CAC9BB">
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,19,0" width="619" height="60">
<param name="movie" value="../images/jd.swf">
<param name="quality" value="high"><param name="BGCOLOR" value="#CAC9BB">
<embed src="../images/jd.swf" quality="high" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" width="619" height="60"></embed>
</object></td>
</tr>
</table></td>
</tr>
<tr>
<td>
<table cellpadding="0" cellspacing="1" bgcolor="#CCCCCC" >
<tr>
<td height="26" bgcolor="#707070" width="222"> </td>
<td height="26" width="70" bgcolor="#707070" class="unnamed2"> <div align="center"><a href="http://www.jdon.com/index.html" class="a03">首 页</a></div></td>
<td height="26" width="70" bgcolor="#707070" class="unnamed2"> <div align="center"><a href="http://www.jdon.com/design.htm" class="a03">设计研究</a></div></td>
<td height="26" width="70" bgcolor="#707070" class="unnamed2"> <div align="center"><a href="http://www.jdon.com/product.htm" class="a03">构件产品</a></div></td>
<td height="26" width="70" bgcolor="#707070" class="unnamed2"> <div align="center"><a href="http://www.jdon.com/trainning.htm" class="a03">培训咨询</a></div></td>
<td height="26" width="70" bgcolor="#707070"> <div align="center" class="unnamed2"><a href="http://www.jdon.com/jdonframework/" class="a03">Jdon框架</a></div></td>
<td height="26" width="70" bgcolor="#707070"> <div align="center" class="unnamed2"><a href="http://www.jdon.com/jive/index.jsp" class="a03">论坛</a></div></td>
</tr></table>
</td>
</tr>
</table>
<table width="750" border="0" cellspacing="0" cellpadding="0" align="center">
<tr>
<td height="11" colspan="7" bgcolor="#FFFFFF" class="bianxian">
<table width="100%" border="0" cellspacing="0" cellpadding="0" height="1" bordercolor="#000000">
<tr>
<td>
<table width="100%" border="0" cellspacing="0" cellpadding="0" height="2" bgcolor="#000000">
<tr>
<td></td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td bgcolor="#FFFFFF" valign="top">
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr>
<td width="130" valign="top" bgcolor="#FFFFD7"><table width="100%" border="0" cellspacing="0" cellpadding="3" height="200" align="center">
<tr>
<td align="left" valign="top"><!-- #BeginEditable "Menu" --> <!-- #EndEditable --> </td>
</tr>
<tr>
<td align="right">
<p><a href="http://www.jdon.com/trainning/jiaocheng.htm" target="_blank"><font color="#FF9999"><strong>在线教程</strong></font><br>
<font color="#555555"> 原创教程区</font></a></p>
<p><a href="http://www.jdon.com/jdonframework/app.htm" target="_blank"><font color="#FF9999"><strong>Jdon框架</strong></font><br>
<font color="#555555"> 在线运行演示</font></a></p>
<br>
<div id=vgad ></div>
<!-- #BeginEditable "Menu2" --> <!-- #EndEditable -->
</td>
</tr>
</table>
</td>
<td width="1" height="100%" >
<table height="100%" cellpadding="0" cellspacing="0" background="../images/blackpoint.gif" >
<tr><td> <img name="" src="" width="1" height="1" alt="" ></td></tr></table>
</td >
<td valign="top" >
<table width="100%" border="0" cellspacing="13" cellpadding="2">
<tr>
<td class="article"><!-- #BeginEditable "main" -->
<h3 align="center">设计模式之State</h3>
<p align="center"><a href="http://www.jdon.com/aboutme.htm">板桥里人</a> http://www.jdon.com 2002/4/6/</p>
<p align="center"><a href="../mybook/index.htm" target="_blank"><strong>模式实战书籍《Java实用系统开发指南》</strong></a></p>
<p><i><b>State模式的定义</b></i>: 不同的状态,不同的行为;或者说,每个状态有着相应的行为.</p>
<p><i><b>何时使用</b></i>?<br>
State模式在实际使用中比较多,适合"状态的切换".因为我们经常会使用If elseif else
进行状态切换, 如果针对状态的这样判断切换反复出现,我们就要联想到是否可以采取State模式了.</p>
<p>不只是根据状态,也有根据属性.如果某个对象的属性不同,对象的行为就不一样,这点在数据库系统中出现频率比较高,我们经常会在一个数据表的尾部,加上property属性含义的字段,用以标识记录中一些特殊性质的记录,这种属性的改变(切换)又是随时可能发生的,就有可能要使用State.<br>
</p>
<p><i><b>是否使用?</b></i><br>
在实际使用,类似开关一样的状态切换是很多的,但有时并不是那么明显,取决于你的经验和对系统的理解深度.</p>
<p>这里要阐述的是"开关切换状态" 和" 一般的状态判断"是有一些区别的, "
一般的状态判断"也是有 if..elseif结构,例如:</p>
<p> if (which==1) state="hello";<br>
else if (which==2) state="hi";<br>
else if (which==3) state="bye";<br>
</p>
<p>这是一个 " 一般的状态判断",state值的不同是根据which变量来决定的,which和state没有关系.如果改成:</p>
<p> if (state.euqals("bye")) state="hello";<br>
else if (state.euqals("hello")) state="hi";<br>
else if (state.euqals("hi")) state="bye";<br>
</p>
<p>这就是 "开关切换状态",是将state的状态从"hello"切换到"hi",再切换到""bye";在切换到"hello",好象一个旋转开关,这种状态改变就可以使用State模式了.</p>
<p>如果单纯有上面一种将"hello"-->"hi"-->"bye"-->"hello"这一个方向切换,也不一定需要使用State模式,因为State模式会建立很多子类,复杂化,但是如果又发生另外一个行为:将上面的切换方向反过来切换,或者需要任意切换,就需要State了.</p>
<p>请看下例:</p>
<table width="80%" border="0" cellspacing="3" cellpadding="3">
<tr>
<td bgcolor="#CCCCCC"> <p>public class Context{</p>
<p> private Color state=null;</p>
<p> public void push(){</p>
<p> //如果当前red状态 就切换到blue<br>
if (state==Color.red) state=Color.blue;<br>
<br>
//如果当前blue状态 就切换到green<br>
else if (state==Color.blue) state=Color.green;<br>
<br>
//如果当前black状态 就切换到red<br>
else if (state==Color.black) state=Color.red;<br>
<br>
//如果当前green状态 就切换到black<br>
else if (state==Color.green) state=Color.black;<br>
<br>
Sample sample=new Sample(state);<br>
sample.operate();<br>
}</p>
<p> public void pull(){<br>
<br>
//与push状态切换正好相反</p>
<p> if (state==Color.green) state=Color.blue;<br>
else if (state==Color.black) state=Color.green;<br>
else if (state==Color.blue) state=Color.red;<br>
else if (state==Color.red) state=Color.black;<br>
<br>
Sample2 sample2=new Sample2(state);<br>
sample2.operate(); <br>
}</p>
<p>}</p></td>
</tr>
</table>
<p>在上例中,我们有两个动作push推和pull拉,这两个开关动作,改变了Context颜色,至此,我们就需要使用State模式优化它.</p>
<p>另外注意:但就上例,state的变化,只是简单的颜色赋值,这个具体行为是很简单的,State适合巨大的具体行为,因此在,就本例,实际使用中也不一定非要使用State模式,这会增加子类的数目,简单的变复杂.</p>
<p>例如: 银行帐户, 经常会在Open 状态和Close状态间转换.</p>
<p>例如: 经典的TcpConnection, Tcp的状态有创建 侦听 关闭三个,并且反复转换,其创建 侦听 关闭的具体行为不是简单一两句就能完成的,适合使用State</p>
<p>例如:信箱POP帐号, 会有四种状态, start HaveUsername Authorized quit,每个状态对应的行为应该是比较大的.适合使用State</p>
<p>例如:在工具箱挑选不同工具,可以看成在不同工具中切换,适合使用State.如 具体绘图程序,用户可以选择不同工具绘制方框
直线 曲线,这种状态切换可以使用State.</p>
<p><i><b>如何使用</b></i><br>
State需要两种类型实体参与:</p>
<p>1.state manager 状态管理器 ,就是开关 ,如上面例子的Context实际就是一个state manager,
在state manager中有对状态的切换动作.<br>
2.用抽象类或接口实现的父类,,不同状态就是继承这个父类的不同子类.</p>
<p>以上面的Context为例.我们要修改它,建立两个类型的实体.<br>
<b>第一步: 首先建立一个父类:</b></p>
<table width="80%" border="0" cellspacing="3" cellpadding="3" bgcolor="#FFFFFF">
<tr>
<td bgcolor="#CCCCCC"> <p>public abstract class State{</p>
<p> public abstract void handlepush(Context c);<br>
public abstract void handlepull(Context c);<br>
public abstract void getcolor();</p>
<p>}</p></td>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -