声明:
本文只为方便我个人查阅和理解,详细的分析以及源代码请移步 原作者的博客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");
}
}
}