状态模式-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("进入黑名单,将禁止登陆和使用本系统!!!");
	}

}

在这里插入图片描述

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