读《研磨设计模式》-代码笔记-状态模式-State_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > 读《研磨设计模式》-代码笔记-状态模式-State

读《研磨设计模式》-代码笔记-状态模式-State

 2012/10/15 10:38:12  bylijinnan  程序员俱乐部  我要评论(0)
  • 摘要:声明:本文只为方便我个人查阅和理解,详细的分析以及源代码请移步原作者的博客http://chjavach.iteye.com/importjava.util.HashMap;importjava.util.Map;/**考虑一个投票的应用:*一个用户只能投一票,若一个用户反复投票,而且投票次数超过5,则认为是恶意刷票,撤消投票记录并取消投票资格*若超过8次,则加入黑名单并禁止再使用系统*/interfaceIVoteState
  • 标签:笔记 研磨设计模式 代码 模式 设计 设计模式
声明:
本文只为方便我个人查阅和理解,详细的分析以及源代码请移步 原作者的博客http://chjavach.iteye.com/



import java.util.HashMap;
import java.util.Map;

/*
 * 考虑一个投票的应用:
 * 一个用户只能投一票,若一个用户反复投票,而且投票次数超过5,则认为是恶意刷票,撤消投票记录并取消投票资格
 * 若超过8次,则加入黑名单并禁止再使用系统
 */

interface IVoteState {
	
	/**
	 * @param user	投票的用户
	 * @param voteItem 投票选项
	 * @param context 
	 */
	public void vote(String user, String voteItem, VoteContext context);
	
}


//正常投票
class NormalVoteState implements IVoteState {

	public void vote(String user, String voteItem, VoteContext context) {
		context.getMapVoteItem().put(user, voteItem);
		System.out.println("投票成功");
	}
	
}
//重复投票
class RepeatVoteState implements IVoteState {
	
	public void vote(String user, String voteItem, VoteContext context) {
		System.out.println("请不要重复投票");
	}
	
}
//恶意投票
class SpiteVoteState implements IVoteState {
	
	public void vote(String user, String voteItem, VoteContext context) {
		context.getMapVoteItem().remove(user);
		System.out.println("你有恶意刷票行为,取消投票资格!");
	}
	
}
//黑名单
class BlackVoteState implements IVoteState {
	
	public void vote(String user, String voteItem, VoteContext context) {
		System.out.println("进入黑名单");
	}
	
}


class VoteContext {
	
	//通常会维护(持有)一个State对象
	private IVoteState state;
	//Map<用户,投票项>
	private Map<String, String> mapVoteItem = new HashMap<String, String>();
	//Map<用户,投票次数>
	private Map<String, Integer> mapVoteCount = new HashMap<String, Integer>();
	
	//在Context里面进行状态的切换
	public void vote(String user, String voteItem) {
		Integer voteCount = mapVoteCount.get(user);
		if (voteCount == null) {
			voteCount = 0;
		}
		voteCount++;
		mapVoteCount.put(user, voteCount);
		if (voteCount == 1) {
			state = new NormalVoteState();
		} else if (voteCount > 1 && voteCount < 5) {
			state = new RepeatVoteState();
		} else if (voteCount >= 5 && voteCount < 8) {
			state = new SpiteVoteState();
		} else if (voteCount >= 8) {
			state = new BlackVoteState();
		}
		
		state.vote(user, voteItem, this);
		
	}
	
	public Map<String, String> getMapVoteItem() {
		return mapVoteItem;
	}
}


/*
 * 假如我们现在有这样一个需求:投票成功的用户将获得积分奖励,那就势必要更改VoteContext的Vote方法:
   if (voteCount == 1) {
			state = new NormalVoteStateWithPrice();
	}
	......
 * 这就是书上说的不完美的OCP体验
 */
class NormalVoteStateWithPrice extends NormalVoteState {
	
	public void vote(String user, String voteItem, VoteContext context) {
		super.vote(user, voteItem, context);
		System.out.println("奖励积分:10");
	}
}


/*
 * 上面的示例,是在Context里面进行状态的切换
 * 状态的切换也可以在状态的处理类中实现
 * 这种情况下,若有新的需求(例如新增一种状态),则可增加一个IVoteState而不必修改已有代码
 */
interface IVoteStatee {
	
	public void vote(String user, String voteItem, VoteContextt context);
	
}


//正常投票
class NormalVoteStatee implements IVoteStatee {

	public void vote(String user, String voteItem, VoteContextt context) {
		context.getMapVoteItem().put(user, voteItem);
		System.out.println("投票成功");
		//正常投票完成,维护下一个状态,同一个人再投票就重复了
		context.getMapState().put(user, new RepeatVoteStatee());
		
	}
	
}
//重复投票
class RepeatVoteStatee implements IVoteStatee {
	
	public void vote(String user, String voteItem, VoteContextt context) {
		System.out.println("请不要重复投票");
		if (context.getMapVoteCount().get(user) >= 4) {
			context.getMapState().put(user, new SpiteVoteStatee());
		}
	}
	
}
//恶意投票
class SpiteVoteStatee implements IVoteStatee {
	
	public void vote(String user, String voteItem, VoteContextt context) {
		context.getMapVoteItem().remove(user);
		System.out.println("你有恶意刷票行为,取消投票资格!");
		if (context.getMapVoteCount().get(user) >= 7) {
			context.getMapState().put(user, new BlackVoteStatee());
		}
	}
	
}
//黑名单
class BlackVoteStatee implements IVoteStatee {
	
	public void vote(String user, String voteItem, VoteContextt context) {
		System.out.println("进入黑名单");
	}
	
}


class VoteContextt {
	
	//Map<用户,本用户投票后对应的状态>
	private Map<String, IVoteStatee> mapState = new HashMap<String, IVoteStatee>();
	//Map<用户,投票项>
	private Map<String, String> mapVoteItem = new HashMap<String, String>();
	//Map<用户,投票次数>
	private Map<String, Integer> mapVoteCount = new HashMap<String, Integer>();
	
	public void vote(String user, String voteItem) {
		
		//1.投票数加1
		Integer voteCount = mapVoteCount.get(user);
		if (voteCount == null) {
			voteCount = 0;
		}
		voteCount++;
		mapVoteCount.put(user, voteCount);
		
		//2.维护状态
		IVoteStatee state = mapState.get(user);
		if (state == null) {
			state = new NormalVoteStatee();
		}
		state.vote(user, voteItem, this);
	}

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

	public Map<String, String> getMapVoteItem() {
		return mapVoteItem;
	}

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

//这个类是用来测试的
public class StatePattern {

	public static void main(String[] args) {
		//测试-状态切换在Context里实现
		VoteContext context = new VoteContext();
		for (int i = 0; i < 8; i++) {
			context.vote("Tom", "A");
		}
		
		System.out.println();
		
		//测试-状态切换由状态实现类切换
		VoteContextt contextt = new VoteContextt();
		for (int i = 0; i < 8; i++) {
			contextt.vote("Tom", "A");
		}
	}

}
发表评论
用户名: 匿名