1. 定义
允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。
状态模式主要使用场景有两个
* 一个对象的行为取决于它的状态,并且它必须在运行时刻根据它的状态改变行为
* 一个操作中含有庞大的分支结构,并且这些分支取决于对象的状态
2. 类图
3. 实例
package com.jerry.designpattern; /** * * @author Jerry * @date 2015年1月31日 下午3:06:54 */ public interface VoteState { void vote(String user, String voteItem, VoteManager voteManager); } package com.jerry.designpattern; /** * * @author Jerry * @date 2015年1月31日 下午3:15:03 */ public class NormalVoteState implements VoteState{ @Override public void vote(String user, String voteItem, VoteManager voteManager) { // TODO Auto-generated method stub voteManager.getVoteMap().put(user, voteItem); System.out.println("恭喜你投票成功"); } } package com.jerry.designpattern; /** * * @author Jerry * @date 2015年1月31日 下午3:16:48 */ public class RepeatVoteState implements VoteState{ @Override public void vote(String user, String voteItem, VoteManager voteManager) { // TODO Auto-generated method stub System.out.println("不好意思,您已经投过票了,不允许重复投票"); } } package com.jerry.designpattern; /** * * @author Jerry * @date 2015年1月31日 下午3:17:54 */ public class SpiteVoteState implements VoteState{ @Override public void vote(String user, String voteItem, VoteManager voteManager) { // TODO Auto-generated method stub System.out.println("您存在恶意刷票行为,取消投票"); voteManager.getVoteMap().remove(user); } } package com.jerry.designpattern; /** * * @author Jerry * @date 2015年1月31日 下午3:19:17 */ public class BlackVoteState implements VoteState{ @Override public void vote(String user, String voteItem, VoteManager voteManager) { // TODO Auto-generated method stub System.out.println("你是黑名单用户,禁止使用本系统"); } } package com.jerry.designpattern; import java.util.HashMap; import java.util.Map; /** * * @author Jerry * @date 2015年1月31日 下午3:08:20 */ public class VoteManager { //保存用户投票的选项 private Map<String, String> voteMap = new HashMap<>(); //保存用户投票数量 private Map<String, Integer> voteMapCount = new HashMap<>(); private VoteState voteState; public Map<String, String> getVoteMap() { return voteMap; } public void vote(String user, String voteItem) { Integer voteCount = voteMapCount.get(user); if (voteCount == null) { voteCount = 0; } voteCount++; voteMapCount.put(user, voteCount); if (voteCount == 1) { voteState = new NormalVoteState(); } else if (voteCount < 5) { voteState = new RepeatVoteState(); } else if (voteCount < 8) { voteState = new SpiteVoteState(); } else { voteState = new BlackVoteState(); } voteState.vote(user, voteItem, this); } } package com.jerry.designpattern; /** * * @author Jerry * @date 2015年1月31日 下午3:23:12 */ public class Client { public static void main(String[] args) { VoteManager vm = new VoteManager(); for (int i = 0; i < 10; i++) { vm.vote("jerry", "A"); } } }
4. 优缺点
状态模式有以下优点:
* 简化应用逻辑控制
* 更好的分离状态和行为
* 更好的扩张性
* 显示化进行状态转换
状态模式有个显著的缺点,一个状态对应一个状态处理类,使系统引入太多的状态类,造成程序的杂乱
5. 小结
大家会发现状态模式和策略模式的结构完全是一样的,但是,它们的目的、实现、本质却是完全不一样的。行为之间的特性是状态模式和策略模式一个很重要的区别,
状态模式的行为是平行的,不可替换的,而策略模式的行为是平等的,可替换的。