java 状态模式 同步_JAVA设计模式之状态模式
在閻宏博士的《JAVA與模式》一書中開頭是這樣描述狀態(State)模式的:
狀態模式,又稱狀態對象模式(Pattern of Objects for States),狀態模式是對象的行為模式。
狀態模式允許一個對象在其內部狀態改變的時候改變其行為。這個對象看上去就像是改變了它的類一樣。
狀態模式的結構
用一句話來表述,狀態模式把所研究的對象的行為包裝在不同的狀態對象里,每一個狀態對象都屬于一個抽象狀態類的一個子類。狀態模式的意圖是讓一個對象在其內部狀態改變的時候,其行為也隨之改變。狀態模式的示意性類圖如下所示:
狀態模式所涉及到的角色有:
● 環境(Context)角色,也成上下文:定義客戶端所感興趣的接口,并且保留一個具體狀態類的實例。這個具體狀態類的實例給出此環境對象的現有狀態。
● 抽象狀態(State)角色:定義一個接口,用以封裝環境(Context)對象的一個特定的狀態所對應的行為。
● 具體狀態(ConcreteState)角色:每一個具體狀態類都實現了環境(Context)的一個狀態所對應的行為。
源代碼
環境角色類
public classContext {//持有一個State類型的對象實例
privateState state;public voidsetState(State state) {this.state =state;
}/*** 用戶感興趣的接口方法*/
public voidrequest(String sampleParameter) {//轉調state來處理
state.handle(sampleParameter);
}
}
抽象狀態類
public interfaceState {/*** 狀態對應的處理*/
public voidhandle(String sampleParameter);
}
具體狀態類
public class ConcreteStateA implementsState {
@Overridepublic voidhandle(String sampleParameter) {
System.out.println("ConcreteStateA handle :" +sampleParameter);
}
}
public class ConcreteStateB implementsState {
@Overridepublic voidhandle(String sampleParameter) {
System.out.println("ConcreteStateB handle :" +sampleParameter);
}
}
客戶端類
public classClient {public static voidmain(String[] args){//創建狀態
State state = newConcreteStateB();//創建環境
Context context = newContext();//將狀態設置到環境中
context.setState(state);//請求
context.request("test");
}
}
從上面可以看出,環境類Context的行為request()是委派給某一個具體狀態類的。通過使用多態性原則,可以動態改變環境類Context的屬性State的內容,使其從指向一個具體狀態類變換到指向另一個具體狀態類,從而使環境類的行為request()由不同的具體狀態類來執行。
使用場景
考慮一個在線投票系統的應用,要實現控制同一個用戶只能投一票,如果一個用戶反復投票,而且投票次數超過5次,則判定為惡意刷票,要取消該用戶投票的資格,當然同時也要取消他所投的票;如果一個用戶的投票次數超過8次,將進入黑名單,禁止再登錄和使用系統。
要使用狀態模式實現,首先需要把投票過程的各種狀態定義出來,根據以上描述大致分為四種狀態:正常投票、反復投票、惡意刷票、進入黑名單。然后創建一個投票管理對象(相當于Context)。
系統的結構圖如下所示:
源代碼
抽象狀態類
public interfaceVoteState {/*** 處理狀態對應的行為
*@paramuser 投票人
*@paramvoteItem 投票項
*@paramvoteManager 投票上下文,用來在實現狀態對應的功能處理的時候,
* 可以回調上下文的數據*/
public voidvote(String user,String voteItem,VoteManager voteManager);
}
具體狀態類——正常投票
public class NormalVoteState implementsVoteState {
@Overridepublic voidvote(String user, String voteItem, VoteManager voteManager) {//正常投票,記錄到投票記錄中
voteManager.getMapVote().put(user, voteItem);
System.out.println("恭喜投票成功");
}
}
具體狀態類——重復投票
public class RepeatVoteState implementsVoteState {
@Overridepublic voidvote(String user, String voteItem, VoteManager voteManager) {//重復投票,暫時不做處理
System.out.println("請不要重復投票");
}
}
具體狀態類——惡意刷票
public class SpiteVoteState implementsVoteState {
@Overridepublic voidvote(String user, String voteItem, VoteManager voteManager) {//惡意投票,取消用戶的投票資格,并取消投票記錄
String str =voteManager.getMapVote().get(user);if(str != null){
voteManager.getMapVote().remove(user);
}
System.out.println("你有惡意刷屏行為,取消投票資格");
}
}
具體狀態類——黑名單
public class BlackVoteState implementsVoteState {
@Overridepublic voidvote(String user, String voteItem, VoteManager voteManager) {//記錄黑名單中,禁止登錄系統
System.out.println("進入黑名單,將禁止登錄和使用本系統");
}
}
環境類
public classVoteManager {//持有狀體處理對象
private VoteState state = null;//記錄用戶投票的結果,Map對應Map
private Map mapVote = new HashMap();//記錄用戶投票次數,Map對應Map
private Map mapVoteCount = new HashMap();/*** 獲取用戶投票結果的Map*/
public MapgetMapVote() {returnmapVote;
}/*** 投票
*@paramuser 投票人
*@paramvoteItem 投票的選項*/
public voidvote(String user,String voteItem){//1.為該用戶增加投票次數//從記錄中取出該用戶已有的投票次數
Integer oldVoteCount =mapVoteCount.get(user);if(oldVoteCount == null){
oldVoteCount= 0;
}
oldVoteCount+= 1;
mapVoteCount.put(user, oldVoteCount);//2.判斷該用戶的投票類型,就相當于判斷對應的狀態//到底是正常投票、重復投票、惡意投票還是上黑名單的狀態
if(oldVoteCount == 1){
state= newNormalVoteState();
}else if(oldVoteCount > 1 && oldVoteCount < 5){
state= newRepeatVoteState();
}else if(oldVoteCount >= 5 && oldVoteCount <8){
state= newSpiteVoteState();
}else if(oldVoteCount > 8){
state= newBlackVoteState();
}//然后轉調狀態對象來進行相應的操作
state.vote(user, voteItem, this);
}
}
客戶端類
public classClient {public static voidmain(String[] args) {
VoteManager vm= newVoteManager();for(int i=0;i<9;i++){
vm.vote("u1","A");
}
}
}
運行結果如下:
從上面的示例可以看出,狀態的轉換基本上都是內部行為,主要在狀態模式內部來維護。比如對于投票的人員,任何時候他的操作都是投票,但是投票管理對象的處理卻不一定一樣,會根據投票的次數來判斷狀態,然后根據狀態去選擇不同的處理。
認識狀態模式
● 狀態和行為
所謂對象的狀態,通常指的就是對象實例的屬性的值;而行為指的就是對象的功能,再具體點說,行為大多可以對應到方法上。
狀態模式的功能就是分離狀態的行為,通過維護狀態的變化,來調用不同狀態對應的不同功能。也就是說,狀態和行為是相關聯的,它們的關系可以描述為:狀態決定行為。
由于狀態是在運行期被改變的,因此行為也會在運行期根據狀態的改變而改變。
● 行為的平行性
注意平行線而不是平等性。所謂平行性指的是各個狀態的行為所處的層次是一樣的,相互獨立的、沒有關聯的,是根據不同的狀態來決定到底走平行線的哪一條。行為是不同的,當然對應的實現也是不同的,相互之間是不可替換的。
而平等性強調的是可替換性,大家是同一行為的不同描述或實現,因此在同一個行為發生的時候,可以根據條件挑選任意一個實現來進行相應的處理。
大家可能會發現狀態模式的結構和策略模式的結構完全一樣,但是,它們的目的、實現、本質卻是完全不一樣的。還有行為之間的特性也是狀態模式和策略模式一個很重要的區別,狀態模式的行為是平行性的,不可相互替換的;而策略模式的行為是平等性的,是可以相互替換的。
● 環境和狀態處理對象
在狀態模式中,環境(Context)是持有狀態的對象,但是環境(Context)自身并不處理跟狀態相關的行為,而是把處理狀態的功能委托給了狀態對應的狀態處理類來處理。
在具體的狀態處理類中經常需要獲取環境(Context)自身的數據,甚至在必要的時候會回調環境(Context)的方法,因此,通常將環境(Context)自身當作一個參數傳遞給具體的狀態處理類。
客戶端一般只和環境(Context)交互。客戶端可以用狀態對象來配置一個環境(Context),一旦配置完畢,就不再需要和狀態對象打交道了。客戶端通常不負責運行期間狀態的維護,也不負責決定后續到底使用哪一個具體的狀態處理對象。
總結
以上是生活随笔為你收集整理的java 状态模式 同步_JAVA设计模式之状态模式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 国航修飞机用电脑吗(国航修飞机工资待遇)
- 下一篇: asp.net html2canvas,