免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
狀態(tài)模式(State pattern)
一、引子

  狀態(tài)模式自身結(jié)構(gòu)非常簡(jiǎn)單——前面剛剛介紹了幾個(gè)結(jié)構(gòu)比較簡(jiǎn)單的設(shè)計(jì)模式,和他們一樣,狀態(tài)模式在具體實(shí)現(xiàn)上留下了可變換的余地。我前面已經(jīng)介紹過它的孿生兄妹策略模式了,大家可以兩者比較著閱讀。本文將會(huì)討論兩者的區(qū)別。

  二、定義與結(jié)構(gòu)

  GOF《設(shè)計(jì)模式》中給狀態(tài)模式下的定義為:允許一個(gè)對(duì)象在其內(nèi)部狀態(tài)改變時(shí)改變它的行為。這個(gè)對(duì)象看起來似乎修改了它的類。看起來,狀態(tài)模式好像是神通廣大——居然能夠“修改自身的類”!

能夠讓程序根據(jù)不同的外部情況來做出不同的響應(yīng),最直接的方法就是在程序中將這些可能發(fā)生的外部情況全部考慮到,使用if else語句來進(jìn)行代碼響應(yīng)選擇。但是這種方法對(duì)于復(fù)雜一點(diǎn)的狀態(tài)判斷,就會(huì)顯得雜亂無章,容易產(chǎn)生錯(cuò)誤;而且增加一個(gè)新的狀態(tài)將會(huì)帶來大量的修改。這個(gè)時(shí)候“能夠修改自身”的狀態(tài)模式的引入也許是個(gè)不錯(cuò)的主意。

  狀態(tài)模式可以有效的替換充滿在程序中的if else語句:將不同條件下的行為封裝在一個(gè)類里面,再給這些類一個(gè)統(tǒng)一的父類來約束他們。來看一下狀態(tài)模式的角色組成吧:

  1) 使用環(huán)境(Context)角色:客戶程序是通過它來滿足自己的需求。它定義了客戶程序需要的接口;并且維護(hù)一個(gè)具體狀態(tài)角色的實(shí)例,這個(gè)實(shí)例來決定當(dāng)前的狀態(tài)。

  2) 狀態(tài)(State)角色:定義一個(gè)接口以封裝與使用環(huán)境角色的一個(gè)特定狀態(tài)相關(guān)的行為。

  3) 具體狀態(tài)(Concrete State)角色:實(shí)現(xiàn)狀態(tài)角色定義的接口。

  類圖如下,結(jié)構(gòu)非常簡(jiǎn)單也與策略模式非常相似。

 

 


  三、實(shí)現(xiàn)

  由于狀態(tài)模式結(jié)構(gòu)非常簡(jiǎn)單,所以在這里羅列一些反映狀態(tài)模式實(shí)現(xiàn)結(jié)構(gòu)的代碼沒有什么太大的作用。如果你有興趣的話可以按照上面類圖來編寫一下。

  在引子中已經(jīng)提到,狀態(tài)模式在具體實(shí)現(xiàn)上存在不同的方案。因此這里重點(diǎn)就這些不同的實(shí)現(xiàn)方式進(jìn)行介紹和討論。

首先,實(shí)現(xiàn)時(shí)是否將狀態(tài)角色、具體狀態(tài)角色暴露給客戶程序?按照GOF的建議是不希望將狀態(tài)角色暴露給客戶程序的,與客戶程序打交道的僅僅是使用環(huán)境角色,客戶是不知道系統(tǒng)是怎么實(shí)現(xiàn)的,更不關(guān)心什么有幾個(gè)具體狀態(tài)。但是當(dāng)使用環(huán)境角色中的初始狀態(tài)緊緊依賴于客戶程序時(shí),適乎暴露是在所難免的——這就與策略模式異常相似了!

  具體狀態(tài)角色中的行為一般是與使用環(huán)境角色密切相關(guān)的。因此這里便有了一個(gè)小細(xì)節(jié):我們把使用環(huán)境角色作為參數(shù)傳遞進(jìn)入具體狀態(tài)角色后,是在具體狀態(tài)角色中來實(shí)現(xiàn)狀態(tài)響應(yīng)行為;還是僅僅調(diào)用在使用環(huán)境角色中已經(jīng)實(shí)現(xiàn)了的方法?由于這些行為往往與使用環(huán)境角色相關(guān),所以按照《重構(gòu)》一書的“指導(dǎo)”——后一種實(shí)現(xiàn)方法是比較地道的。

  從定義可知,狀態(tài)模式是要應(yīng)對(duì)狀態(tài)轉(zhuǎn)換的。那么狀態(tài)的轉(zhuǎn)換在哪里定義呢?你可以選擇在使用環(huán)境角色的代碼中來表現(xiàn)出來,當(dāng)然這便意味著狀態(tài)轉(zhuǎn)變的規(guī)則就固定下來了。GOF還給出了另外一種稍微靈活一點(diǎn)的實(shí)現(xiàn)方式:在每一個(gè)具體狀態(tài)角色中來指定后續(xù)狀態(tài)以及何時(shí)進(jìn)行轉(zhuǎn)換。

  其實(shí)在java強(qiáng)大的反射機(jī)制的支持下,我們還可以將狀態(tài)的轉(zhuǎn)換做的更加靈活——我們可以將狀態(tài)轉(zhuǎn)換的規(guī)則寫在.xml等等的配置文件里面甚至是數(shù)據(jù)庫中,我們姑且叫做狀態(tài)轉(zhuǎn)換表。進(jìn)行轉(zhuǎn)換前,根據(jù)狀態(tài)轉(zhuǎn)換表來讀取下一個(gè)狀態(tài),然后利用反射獲得具體的狀態(tài)對(duì)象……??雌饋砗懿诲e(cuò)的樣子,只是效率可能低一些,在企業(yè)應(yīng)用中這應(yīng)該不是最重要的。

  狀態(tài)模式已經(jīng)被我們想象著“實(shí)現(xiàn)”了一番。那么狀態(tài)模式的引入會(huì)給我們的程序帶來哪些優(yōu)勢(shì)呢?前面我們已經(jīng)說過:狀態(tài)模式的引入免除了代碼中復(fù)雜而庸長(zhǎng)的邏輯判斷語句。而且具體狀態(tài)角色將具體狀態(tài)和它對(duì)應(yīng)的行為封裝了起來,這使得增加一種新的狀態(tài)變得簡(jiǎn)單一些。而且如果設(shè)計(jì)合理得話,具體狀態(tài)角色可以被重用(和策略模式一樣,可以考慮使用享元模式來實(shí)現(xiàn))。

  使用狀態(tài)模式也會(huì)帶來一些問題。每個(gè)狀態(tài)對(duì)應(yīng)一個(gè)具體的狀態(tài)類,使得整體分散,邏輯不太清晰。當(dāng)然對(duì)于一個(gè)狀態(tài)非常多的系統(tǒng),狀態(tài)模式帶來的優(yōu)點(diǎn)還是大于它的缺點(diǎn)的。

  由上面的分析就可以很明確的知道什么時(shí)候該使用狀態(tài)模式了。下面是GOF在《設(shè)計(jì)模式》中給出的狀態(tài)模式的適用情況:

  1) 一個(gè)對(duì)象的行為取決于它的狀態(tài), 并且它必須在運(yùn)行時(shí)刻根據(jù)狀態(tài)改變它的行為。

  2) 一個(gè)操作中含有龐大的多分支的條件語句,且這些分支依賴于該對(duì)象的狀態(tài)。

  四、狀態(tài)VS策略

  仔細(xì)對(duì)比狀態(tài)模式和策略模式,難免會(huì)產(chǎn)生疑問:這兩個(gè)明明是一個(gè)東西嘛!下面我們就來分析下兩者區(qū)別。

  首先我要聲明,在實(shí)際應(yīng)用中只要能夠使得你的代碼靈活漂亮起來,何必計(jì)較這些方方面面的差別呢?

BrandonGoldfedder在《模式的樂趣》里是怎么說的:“strategy模式在結(jié)構(gòu)上與state模式非常相似,但是在概念上,他們的目的差異非常大。區(qū)分這兩個(gè)模式的關(guān)鍵是看行為是由狀態(tài)驅(qū)動(dòng)還是由一組算法驅(qū)動(dòng),這條規(guī)則似乎有點(diǎn)隨意,但是在判斷時(shí)還是需要考慮它。通常,State模式的“狀態(tài)”是在對(duì)象內(nèi)部的,Strategy模式的“策略”可以在對(duì)象外部,不過這也不是一條嚴(yán)格、可靠的規(guī)則。”

  我很同意Brandon Goldfedder的觀點(diǎn)。這兩個(gè)模式的劃分,就在于使用的目的是不同的——策略模式用來處理算法變化,而狀態(tài)模式則是處理狀態(tài)變化(好玄乎阿)。

  策略模式中,算法是否變化完全是由客戶程序開決定的,而且往往一次只能選擇一種算法,不存在算法中途發(fā)生變化的情況。從《深入淺出策略模式》中的例子可以很好的看出。

  而狀態(tài)模式如定義中所言,在它的生命周期中存在著狀態(tài)的轉(zhuǎn)變和行為得更改,而且狀態(tài)變化是一個(gè)線性的整體;對(duì)于客戶程序來言,這種狀態(tài)變化往往是透明的。
using System; 
 
namespace DesignPattern.State 

    
/**////  
    
/// 抽象狀態(tài) 狀態(tài)接口 
    
///  

    public interface ITcpState 
    

        
void Open(); 
        
void Close(); 
        
void Acknowledge(); 
    }
 
 
    
/**////  
    
/// 此類相當(dāng)于Context 
    
///  

    public class TcpConnection 
    

        
private ITcpState state; 
 
        
public ITcpState State 
        

            
set{this.state=value;} 
        }
 
 
        
public void Open() 
        

            
this.State=new TcpEstablished(); 
            
this.state.Open(); 
            
this.State=new TcpListen(); 
        }
 
 
        
public void Close() 
        

            
this.state.Close(); 
            
this.State=new TcpClosed(); 
        }
 
 
        
public void Acknowledge() 
        

            
this.state.Acknowledge(); 
        }
 
    }
 
 
    
public class TcpEstablished : ITcpState 
    

         
        
public void Open() 
        

            Console.WriteLine(
"Have opened,can not open again!"); 
        }
 
 
        
public void Close() 
        

            Console.WriteLine(
"Closing"); 
        }
 
 
        
public void Acknowledge() 
        

            Console.WriteLine(
"TcpEstablished!"); 
        }
 
 
    }
 
 
    
public class TcpListen : ITcpState 
    

        
public void Open() 
        

            Console.WriteLine(
"Have opened,can not open again!"); 
        }
 
 
        
public void Close() 
        

            Console.WriteLine(
"Closing"); 
        }
 
 
        
public void Acknowledge() 
        

            Console.WriteLine(
"TcpListen!"); 
        }
 
 
 
    }
 
 
    
public class TcpClosed : ITcpState 
    

        
public void Open() 
        

            Console.WriteLine(
"Openning"); 
        }
 
 
        
public void Close() 
        

            Console.WriteLine(
"Have closed,can not close again!"); 
        }
 
 
        
public void Acknowledge() 
        

            Console.WriteLine(
"TcpClosed!"); 
        }
 
 
    }
 
 
    
public class Client 
    

        
public static void Main() 
        

            TcpConnection tcpcon
=new TcpConnection(); 
            tcpcon.Open(); 
            tcpcon.Acknowledge(); 
            tcpcon.Open(); 
            tcpcon.Close(); 
            tcpcon.Acknowledge(); 
            tcpcon.Close(); 
        }
 
    }
 
}
 


  五、總結(jié)

  比較籠統(tǒng)地介紹了下狀態(tài)模式,并將它和非常相近的策略模式進(jìn)行了比較。歡迎大家學(xué)習(xí)指正。
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
結(jié)構(gòu)型模式之享元模式
設(shè)計(jì)模式24:State Pattern (狀態(tài)模式)
博客園 - 探索設(shè)計(jì)模式(七):創(chuàng)建型模式專題總結(jié)(Creational Pattern)
策略模式 C#策略模式(Strategy Pattern)實(shí)例教程
C#設(shè)計(jì)模式(5)——建造者模式(Builder Pattern)
C#設(shè)計(jì)模式學(xué)習(xí)筆記:(21)訪問者模式
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服