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. 小结

  大家会发现状态模式和策略模式的结构完全是一样的,但是,它们的目的、实现、本质却是完全不一样的。行为之间的特性是状态模式和策略模式一个很重要的区别,

状态模式的行为是平行的,不可替换的,而策略模式的行为是平等的,可替换的。

posted on 2015-01-31 16:20  爱生活的夜  阅读(127)  评论(0编辑  收藏  举报