文章詳情頁
java設(shè)計(jì)模式之State
瀏覽:89日期:2024-06-27 11:00:29
內(nèi)容: State的定義: 不同的狀態(tài),不同的行為;或者說,每個(gè)狀態(tài)有著相應(yīng)的行為.何時(shí)使用?State模式在實(shí)際使用中比較多,適合'狀態(tài)的切換'.因?yàn)槲覀兘?jīng)常會(huì)使用If elseif else 進(jìn)行狀態(tài)切換, 如果針對(duì)狀態(tài)的這樣判斷切換反復(fù)出現(xiàn),我們就要聯(lián)想到是否可以采取State模式了.不只是根據(jù)狀態(tài),也有根據(jù)屬性.如果某個(gè)對(duì)象的屬性不同,對(duì)象的行為就不一樣,這點(diǎn)在數(shù)據(jù)庫系統(tǒng)中出現(xiàn)頻率比較高,我們經(jīng)常會(huì)在一個(gè)數(shù)據(jù)表的尾部,加上property屬性含義的字段,用以標(biāo)識(shí)記錄中一些特殊性質(zhì)的記錄,這種屬性的改變(切換)又是隨時(shí)可能發(fā)生的,就有可能要使用State.是否使用?在實(shí)際使用,類似開關(guān)一樣的狀態(tài)切換是很多的,但有時(shí)并不是那么明顯,取決于你的經(jīng)驗(yàn)和對(duì)系統(tǒng)的理解深度.這里要闡述的是'開關(guān)切換狀態(tài)' 和' 一般的狀態(tài)判斷'是有一些區(qū)別的, ' 一般的狀態(tài)判斷'也是有 if..elseif結(jié)構(gòu),例如:if (which==1) state='hello';else if (which==2) state='hi';else if (which==3) state='bye';這是一個(gè) ' 一般的狀態(tài)判斷',state值的不同是根據(jù)which變量來決定的,which和state沒有關(guān)系.如果改成:if (state.euqals('bye')) state='hello';else if (state.euqals('hello')) state='hi';else if (state.euqals('hi')) state='bye';這就是 '開關(guān)切換狀態(tài)',是將state的狀態(tài)從'hello'切換到'hi',再切換到''bye';在切換到'hello',好象一個(gè)旋轉(zhuǎn)開關(guān),這種狀態(tài)改變就可以使用State模式了.如果單純有上面一種將'hello''hi''bye''hello'這一個(gè)方向切換,也不一定需要使用State模式,因?yàn)镾tate模式會(huì)建立很多子類,復(fù)雜化,但是如果又發(fā)生另外一個(gè)行為:將上面的切換方向反過來切換,或者需要任意切換,就需要State了.請(qǐng)看下例:public class Context{private Color state=null;public void push(){//如果當(dāng)前red狀態(tài) 就切換到blueif (state==Color.red) state=Color.blue;//如果當(dāng)前blue狀態(tài) 就切換到greenelse if (state==Color.blue) state=Color.green;//如果當(dāng)前black狀態(tài) 就切換到redelse if (state==Color.black) state=Color.red;//如果當(dāng)前green狀態(tài) 就切換到blackelse if (state==Color.green) state=Color.black;Sample sample=new Sample(state);sample.operate();}public void pull(){//與push狀態(tài)切換正好相反if (state==Color.green) state=Color.blue;else if (state==Color.black) state=Color.green;else if (state==Color.blue) state=Color.red;else if (state==Color.red) state=Color.black;Sample2 sample2=new Sample2(state);sample2.operate(); }} 在上例中,我們有兩個(gè)動(dòng)作push推和pull拉,這兩個(gè)開關(guān)動(dòng)作,改變了Context顏色,至此,我們就需要使用State模式優(yōu)化它.另外注意:但就上例,state的變化,只是簡單的顏色賦值,這個(gè)具體行為是很簡單的,State適合巨大的具體行為,因此在,就本例,實(shí)際使用中也不一定非要使用State模式,這會(huì)增加子類的數(shù)目,簡單的變復(fù)雜.例如: 銀行帳戶, 經(jīng)常會(huì)在Open 狀態(tài)和Close狀態(tài)間轉(zhuǎn)換.例如: 經(jīng)典的TcpConnection, Tcp的狀態(tài)有創(chuàng)建 偵聽 關(guān)閉三個(gè),并且反復(fù)轉(zhuǎn)換,其創(chuàng)建 偵聽 關(guān)閉的具體行為不是簡單一兩句就能完成的,適合使用State例如:信箱POP帳號(hào), 會(huì)有四種狀態(tài), start HaveUsername Authorized quit,每個(gè)狀態(tài)對(duì)應(yīng)的行為應(yīng)該是比較大的.適合使用State例如:在工具箱挑選不同工具,可以看成在不同工具中切換,適合使用State.如 具體繪圖程序,用戶可以選擇不同工具繪制方框 直線 曲線,這種狀態(tài)切換可以使用State.如何使用State需要兩種類型實(shí)體參與:1.state manager 狀態(tài)管理器 ,就是開關(guān) ,如上面例子的Context實(shí)際就是一個(gè)state manager, 在state manager中有對(duì)狀態(tài)的切換動(dòng)作.2.用抽象類或接口實(shí)現(xiàn)的父類,,不同狀態(tài)就是繼承這個(gè)父類的不同子類.以上面的Context為例.我們要修改它,建立兩個(gè)類型的實(shí)體.第一步: 首先建立一個(gè)父類:public abstract class State{public abstract void handlepush(Context c);public abstract void handlepull(Context c);public abstract void getcolor();} 父類中的方法要對(duì)應(yīng)state manager中的開關(guān)行為,在state manager中 本例就是Context中,有兩個(gè)開關(guān)動(dòng)作push推和pull拉.那么在狀態(tài)父類中就要有具體處理這兩個(gè)動(dòng)作:handlepush() handlepull(); 同時(shí)還需要一個(gè)獲取push或pull結(jié)果的方法getcolor()下面是具體子類的實(shí)現(xiàn):public class BlueState extends State{public void handlepush(Context c){ //根據(jù)push方法'如果是blue狀態(tài)的切換到green' ; c.setState(new GreenState());}public void handlepull(Context c){ //根據(jù)pull方法'如果是blue狀態(tài)的切換到red' ;c.setState(new RedState());}public abstract void getcolor(){ return (Color.blue)}} 同樣 其他狀態(tài)的子類實(shí)現(xiàn)如blue一樣.第二步: 要重新改寫State manager 也就是本例的Context:public class Context{private Sate state=null; //我們將原來的 Color state 改成了新建的State state;//setState是用來改變state的狀態(tài) 使用setState實(shí)現(xiàn)狀態(tài)的切換pulic void setState(State state){this.state=state;}public void push(){//狀態(tài)的切換的細(xì)節(jié)部分,在本例中是顏色的變化,已經(jīng)封裝在子類的handlepush中實(shí)現(xiàn),這里無需關(guān)心state.handlepush(this);//因?yàn)閟ample要使用state中的一個(gè)切換結(jié)果,使用getColor()Sample sample=new Sample(state.getColor());sample.operate(); } public void pull(){state.handlepull(this);Sample2 sample2=new Sample2(state.getColor());sample2.operate(); }} 至此,我們也就實(shí)現(xiàn)了State的refactorying過程.以上只是相當(dāng)簡單的一個(gè)實(shí)例,在實(shí)際應(yīng)用中,handlepush或handelpull的處理是復(fù)雜的.參考資源:the State and StategyHow to implement state-dependent behavior The state patterns Java, java, J2SE, j2se, J2EE, j2ee, J2ME, j2me, ejb, ejb3, JBOSS, jboss, spring, hibernate, jdo, struts, webwork, ajax, AJAX, mysql, MySQL, Oracle, Weblogic, Websphere, scjp, scjd
標(biāo)簽:
Java
相關(guān)文章:
1. Python面向?qū)ο蟪绦蛟O(shè)計(jì)之繼承、多態(tài)原理與用法詳解2. PHP設(shè)計(jì)模式(五)適配器模式Adapter實(shí)例詳解【結(jié)構(gòu)型】3. 淺談JAVA設(shè)計(jì)模式之代理模式4. 實(shí)例講解JAVA設(shè)計(jì)模式之備忘錄模式5. php設(shè)計(jì)模式之策略模式實(shí)例分析【星際爭(zhēng)霸游戲案例】6. java設(shè)計(jì)模式之Flyweight7. PHP設(shè)計(jì)模式中工廠模式深入詳解8. Python面向?qū)ο蟪绦蛟O(shè)計(jì)之靜態(tài)方法、類方法、屬性方法原理與用法分析9. Java設(shè)計(jì)模式之觀察者模式原理與用法詳解10. Java多線程并發(fā)生產(chǎn)者消費(fèi)者設(shè)計(jì)模式實(shí)例解析
排行榜
