狀態模式-state

1、實現在線投票

需求: 在線投票,要實現控制統一用戶只能頭投一票,如果一個用戶反覆投票,而且投票次數超過5次,則判定爲惡意刷票,要取消該用戶投票的資格,當然同時也要取消他所有的投票;如果一個用戶的投票次數超過8次,將進入黑名單,禁止再登錄和使用系統。

2、傳統的解決方案

public class VoteManager2 {
	/**
	 * 記錄用戶投票的結果,map<用戶名稱,投票的選項>
	 */
	private Map<String,String> mapVote = new HashMap<>();
	
	/**
	 * 記錄用戶投票次數
	 */
	private Map<String,Integer> mapVoteCount = new HashMap<>();
	
	/**
	 * 投票
	 * @param user 投票人
	 * @param voteItem 投票的選項
	 */
	public  void vote(String user,String voteItem) {
		//1.先爲該用戶增加投票的次數
		//從記錄中取出已有的投票次數
		Integer oldVoteCount = mapVoteCount.get(user);
		
		if(oldVoteCount == null) {
			oldVoteCount = 0;
		}
		
		oldVoteCount = oldVoteCount + 1;
		
		mapVoteCount.put(user, oldVoteCount);
		
		//2.判斷該用戶投票的類型,到底是正常投票、重複投票,惡意投票
		//還是上黑名單,然後根據投票類型進行相應的操作
		if(oldVoteCount == 1) {
			//正常投票
			mapVote.put(user, voteItem);
			System.out.println("恭喜你獲得投票資格!!!");
		}else if(oldVoteCount >1 && oldVoteCount < 5) {
			//重複投票
			System.out.println("請不要重複投票!!!");
		}else if(oldVoteCount >5 && oldVoteCount < 8) {
			//惡意投票
			//取消用戶的投票資格,並取消投票
			String s = mapVote.get(user);
			if(s!=null) {
				mapVote.remove(user);
			}
			System.out.println("你有惡意刷票行爲,取消投票資格!!!");
		}else if(oldVoteCount >= 8) {
			//黑名單
			//記錄黑名單中,禁止登陸系統
			System.out.println("進入黑名單,將禁止登陸和使用本系統");
			
		}
		
		
	}
}

public class Client {
	
	public static void main(String[] args) {
		VoteManager voteManager = new VoteManager();
		for(int i=0;i<8;i++) {
			voteManager.vote("zhagnsan", "A");
		}
	}
}


存在問題:

一個問題是,如果現在修改某種投票情況所對應的具體功能處理,那就需要在那個大雜燴中,找到相應的代碼塊,然後進行改動。

第二個問題: 如果要添加新的功能,比如投票超過8次但不足10次的,給個機會,只是禁止登陸和使用系統3天,如果再犯,才永久封掉賬號,該怎麼辦呢?那就需要改動投票管理的源代碼。在上面的if-else 結構中再添加一個else if 塊進行處理。

不管哪一種情況,都是在一大堆的控制代碼中找出需要的部分,然後進行修改,這不是個好辦法。那麼該如何實現才能做到: 既能夠很容易地給vote() 方法添加新的功能,又能夠很方便地修改已有的功能處理呢?

3. 使用狀態模式來實現 投票功能


/**
 * 封裝一個投票狀態的行爲
 * @author Administrator
 *
 */
public interface VoteState {
	public void vote(String user, String voteItem, VoteManager voteManager);
}


/**
 * 正常投票
 * @author Administrator
 *
 */
public class NormalVoteState implements VoteState {

	@Override
	public void vote(String user, String voteItem, VoteManager voteManager) {
		//正常投票
		voteManager.getMapVote().put(user, voteItem);
		System.out.println("恭喜你獲得投票資格!!!");
	}

}



public class RepeatVoteState implements VoteState {

	@Override
	public void vote(String user, String voteItem, VoteManager voteManager) {
		//重複投票
		System.out.println("請不要重複投票!!!");
	}

}

public class SpiteVoteState implements VoteState {

	@Override
	public void vote(String user, String voteItem, VoteManager voteManager) {
		// 惡意投票
		//取消用戶的投票資格,並取消投票資格
		String s = voteManager.getMapVote().get(user);
		
		if(s!=null) {
			voteManager.getMapVote().remove(user);
		}
		
		System.out.println("你有惡意刷票行爲,取消投票資格!!!");
	}

}

public class BlackVoteState implements VoteState {

	@Override
	public void vote(String user, String voteItem, VoteManager voteManager) {
	 //黑名單
		//記錄黑名單中,禁止登陸系統了
		System.out.println("進入黑名單,將禁止登陸和使用本系統!!!");
	}

}


/**
 * 投票管理
 * @author Administrator
 *
 */
public class VoteManager {
	
	/**
	 * 持有狀態處理對象
	 */
	private VoteState state = null;
	
	
	/**
	 * 記錄用戶投票的結果,map<用戶名稱,投票的選項>
	 */
	private Map<String,String> mapVote = new HashMap<>();
	
	/**
	 * 記錄用戶投票次數
	 */
	private Map<String,Integer> mapVoteCount = new HashMap<>();

	public void  vote(String user,String voteItem) {
		//1:先爲該用戶增加投票的次數
		mapVoteCount.computeIfAbsent(user, k->0);
		Integer oldVoteCount = mapVoteCount.get(user);
		oldVoteCount++;
		mapVoteCount.put(user, oldVoteCount);
		
		if(oldVoteCount == 1) {
			state = new NormalVoteState();
		}else if(oldVoteCount>1&&oldVoteCount<5) {
			state = new RepeatVoteState();
		}else if(oldVoteCount>=5&&oldVoteCount<8) {
			state = new SpiteVoteState();
		}else if(oldVoteCount > 8) {
			state = new BlackVoteState();
		}
		//然後調轉狀態對象來進行相應的操作
		state.vote(user, voteItem, this);
	}

	public Map<String, String> getMapVote() {
		return mapVote;
	}
	
	

}



public class Client {
	
	public static void main(String[] args) {
		VoteManager voteManager = new VoteManager();
		for(int i=0;i<8;i++) {
			voteManager.vote("zhagnsan", "A");
		}
	}
}



4. 狀態的維護和轉換控制

  • 一是在上下穩重。因爲狀態本身通常被實現爲上下文對象的狀態,因此可以在上下文進行狀態維護,當然也就可以控制狀態的轉換了。前面的 投票的示例就是採用這種方式。
  • 另外一個地方就是在狀態的處理類中。當每個狀態處理對象處理完自身狀態所對應的功能後,可以根據需要指定後繼狀態,以便讓應用能正確處理後續的請求。

代碼示例:

/**
 * 投票管理
 * @author Administrator
 *
 */
public class VoteManager {
	
	/**
	 * 記錄用戶投票的結果,map<用戶名稱,投票的選項>
	 */
	private Map<String,VoteState> mapState = new HashMap<>();
	
	
	/**
	 * 記錄用戶投票的結果,map<用戶名稱,投票的選項>
	 */
	private Map<String,String> mapVote = new HashMap<>();
	
	/**
	 * 記錄用戶投票次數
	 */
	private Map<String,Integer> mapVoteCount = new HashMap<>();

	public void  vote(String user,String voteItem) {
		//1:先爲該用戶增加投票的次數
		mapVoteCount.computeIfAbsent(user, k->0);
		Integer oldVoteCount = mapVoteCount.get(user);
		oldVoteCount++;
		mapVoteCount.put(user, oldVoteCount);
		
		
		
		VoteState state = mapState.get(user);
		
		if(state == null) {
			state = new NormalVoteState();
		}
		
		//然後調轉狀態對象來進行相應的操作
		state.vote(user, voteItem, this);
	}

	public Map<String, String> getMapVote() {
		return mapVote;
	}

	public Map<String, VoteState> getMapState() {
		return mapState;
	}

	public void setMapState(Map<String, VoteState> mapState) {
		this.mapState = mapState;
	}

	public Map<String, Integer> getMapVoteCount() {
		return mapVoteCount;
	}
	
	
	
	
	
	

}

/**
 * 正常投票
 * @author Administrator
 *
 */
public class NormalVoteState implements VoteState {

	@Override
	public void vote(String user, String voteItem, VoteManager voteManager) {
		//正常投票
		voteManager.getMapVote().put(user, voteItem);
		System.out.println("恭喜你獲得投票資格!!!");
		
		//正常投票完成,維護下一個狀態,同一個人再投就重複了
		voteManager.getMapState().put(user, new RepeatVoteState());
	}

}

public class RepeatVoteState implements VoteState {

	@Override
	public void vote(String user, String voteItem, VoteManager voteManager) {
		//重複投票
		System.out.println("請不要重複投票!!!");
		//正常投票完成,維護下一個狀態,重複投票到5次,就算惡意投票
		if(voteManager.getMapVoteCount().get(user) >= 4) {
			voteManager.getMapState().put(user, new SpiteVoteState());
		}

	}

}

public class SpiteVoteState implements VoteState {

	@Override
	public void vote(String user, String voteItem, VoteManager voteManager) {
		// 惡意投票
		//取消用戶的投票資格,並取消投票資格
		String s = voteManager.getMapVote().get(user);
		
		if(s!=null) {
			voteManager.getMapVote().remove(user);
		}
		
		System.out.println("你有惡意刷票行爲,取消投票資格!!!");
		
		//正常投票完成,維護下一個狀態,重複投票到5次,就算惡意投票
		if(voteManager.getMapVoteCount().get(user) >= 7) {
			voteManager.getMapState().put(user, new BlackVoteState());
		}

	}

}


public class BlackVoteState implements VoteState {

	@Override
	public void vote(String user, String voteItem, VoteManager voteManager) {
	 //黑名單
		//記錄黑名單中,禁止登陸系統了
		System.out.println("進入黑名單,將禁止登陸和使用本系統!!!");
	}

}

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章