状态模式介绍
状态模式中的行为是由状态来觉定的,不同的状态下有不同的行为。状态模式和策略模式的结构几乎一样的,但它们的目的、本质却不一样。
状态模式的定义
当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。
状态模式的的UML类图
源码示例:
抽象状态类
public interface VoteState {
public void vote(String user, String voteItem,VoteManage voteManage);
}
具体状态类—-正常投票
public class NormalVoteState implements VoteState {
public void vote(String user, String voteItem, VoteManage voteManage) {
//正常投票,记录到投票记录中
voteManage.getMapVote().put(user, voteItem);
System.out.println("恭喜投票成功.");
}
}
具体状态类—-重复投票
public class RepeatVoteState implements VoteState {
public void vote(String user, String voteItem, VoteManage voteManage) {
//重复投票,暂时不做处理
System.out.println("请不要重复投票");
}
}
具体状态类—-恶意刷票
public class SpiteVoteState implements VoteState {
public void vote(String user, String voteItem, VoteManage voteManage) {
// 恶意投票,取消用户的投票资格,并取消投票记录
String string = voteManage.getMapVote().get(user);
if (string != null) {
voteManage.getMapVote().remove(user);
}
System.out.println("你有恶意刷屏行为,取消投票资格");
}
}
具体状态类—-黑名单
public class BlackVoteState implements VoteState {
public void vote(String user, String voteItem, VoteManage voteManage) {
//记录黑名单中,禁止登录系统
System.out.println("进入黑名单,将禁止登录和使用本系统");
}
}
环境类
public class VoteManage {
//状态处理对象
private VoteState state = null;
//记录投票的结果
private Map<String, String> mapVote = new HashMap<>();
//记录投票的次数
private Map<String, Integer> mapVoteCount = new HashMap<>();
public Map<String, String> getMapVote(){
return mapVote;
}
public void vote(String user,String voteItem){
Integer oldVoteCount = mapVoteCount.get(user);
if (oldVoteCount == null) {
oldVoteCount = 0;
}
oldVoteCount += 1;
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 class Client {
public static void main(String[] args) {
VoteManage voteManage = new VoteManage();
for(int i = 0 ; i < 9 ; i++){
voteManage.vote("uuu", "投一票");
}
}
}
运行结果:
恭喜投票成功.
请不要重复投票
请不要重复投票
请不要重复投票
你有恶意刷屏行为,取消投票资格
你有恶意刷屏行为,取消投票资格
你有恶意刷屏行为,取消投票资格
你有恶意刷屏行为,取消投票资格
进入黑名单,将禁止登录和使用本系统
从上面的示例可以看出,状态的转换基本都是内部行为,主要在状态模式的内部来维护。示例中对应投票的人员,任何时候他的操作都是投票,但是投票管理者处理不是一样,会根据投票的次数来判断状态,然后根据状态选择不同处理。