10. State mode

When the state of the object changes, it also changes its behavior. It's easy to understand! Take QQ as an example. There are several states, online, invisible, busy, etc. Each state corresponds to a different operation, and your friends can also see your state. Therefore, the state mode has two points: 1. Change the state to get different behaviors. 2. Your friends can see your changes at the same time.

State mode allows an object to change its behavior when its internal state changes. This object looks like it has changed its class.

Class Diagram

The State class is a state class, and the Context class can be switched.

Code example

State class:

1.	package com.xtfggef.dp.state;  
2.	  
3.	/** 
4.	 * 状态类的核心类 
5.	 * 2012-12-1 
7.	 * 
8.	 */  
9.	public class State {  
10.	      
11.	    private String value;  
12.	      
13.	    public String getValue() {  
14.	        return value;  
15.	    }  
16.	  
17.	    public void setValue(String value) {  
18.	        this.value = value;  
19.	    }  
20.	  
21.	    public void method1(){  
22.	        System.out.println("execute the first opt!");  
23.	    }  
24.	      
25.	    public void method2(){  
26.	        System.out.println("execute the second opt!");  
27.	    }  
28.	}  

Context class:

1.	package com.xtfggef.dp.state;  
2.	  
3.	/** 
4.	 * 状态模式的切换类   2012-12-1 
5.	 * @author erqing 
6.	 *  
7.	 */  
8.	public class Context {  
9.	  
10.	    private State state;  
11.	  
12.	    public Context(State state) {  
13.	        this.state = state;  
14.	    }  
15.	  
16.	    public State getState() {  
17.	        return state;  
18.	    }  
19.	  
20.	    public void setState(State state) {  
21.	        this.state = state;  
22.	    }  
23.	  
24.	    public void method() {  
25.	        if (state.getValue().equals("state1")) {  
26.	            state.method1();  
27.	        } else if (state.getValue().equals("state2")) {  
28.	            state.method2();  
29.	        }  
30.	    }  
31.	}  

Test category:

1.	public class Test {  
2.	  
3.	    public static void main(String[] args) {  
4.	          
5.	        State state = new State();  
6.	        Context context = new Context(state);  
7.	          
8.	        //设置第一种状态  
9.	        state.setValue("state1");  
10.	        context.method();  
11.	          
12.	        //设置第二种状态  
13.	        state.setValue("state2");  
14.	        context.method();  
15.	    }  
16.	}  

According to this feature, the state mode is used a lot in daily development, especially when building a website, we sometimes hope to distinguish some of their functions based on a certain attribute of the object, such as simple permission control.

The structure of the state pattern

To put it in one sentence, the state pattern packs the behavior of the object under study in different state objects, and each state object belongs to a subclass of an abstract state class. The intent of the state pattern is to make an object change its behavior when its internal state changes.

The roles involved in the state model are:

  The role of the environment (Context), also known as the context: defines the interface that the client is interested in, and retains an instance of a specific state class. The instance of this concrete state class gives the current state of this environment object.

  ● Abstract state (State) role: define an interface to encapsulate the behavior corresponding to a specific state of the Context object.

  ●Concrete State (ConcreteState) role: Each concrete state class implements the behavior corresponding to a state of the environment (Context).

Application scenario

Consider the application of an online voting system, in order to achieve control of the same user can only cast one vote. If a user repeatedly votes and the number of votes exceeds 5 times, it is judged as malicious brushing and the user’s qualification to vote shall be cancelled. To cancel his vote; if a user votes more than 8 times, he will enter the blacklist, and log in and use the system is prohibited.

To use the state mode to achieve, you first need to define the various states of the voting process. According to the above description, it can be roughly divided into four states: normal voting, repeated voting, malicious brushing, and entering the blacklist. Then create a voting management object (equivalent to Context).

 

Abstract state class

 

public interface VoteState {
    /**
     * 处理状态对应的行为
     * @param user    投票人
     * @param voteItem    投票项
     * @param voteManager    投票上下文,用来在实现状态对应的功能处理的时候,
     *                         可以回调上下文的数据
     */
    public void vote(String user,String voteItem,VoteManager voteManager);
}

Specific status class-normal voting

public class NormalVoteState implements VoteState {

    @Override
    public void vote(String user, String voteItem, VoteManager voteManager) {
        //正常投票,记录到投票记录中        
        voteManager.getMapVote().put(user, voteItem);
        System.out.println("恭喜投票成功");
    }

}

Specific status class-repeated voting

public class RepeatVoteState implements VoteState {

    @Override
    public void vote(String user, String voteItem, VoteManager voteManager) {
        //重复投票,暂时不做处理
        System.out.println("请不要重复投票");
    }

}

Specific status class-malicious swipe

public class SpiteVoteState implements VoteState {

    @Override
    public void vote(String user, String voteItem, VoteManager voteManager) {
        // 恶意投票,取消用户的投票资格,并取消投票记录
        String str = voteManager.getMapVote().get(user);
        if(str != null){
            voteManager.getMapVote().remove(user);
        }
        System.out.println("你有恶意刷屏行为,取消投票资格");
    }

}

Specific status class-blacklist

public class BlackVoteState implements VoteState {

    @Override
    public void vote(String user, String voteItem, VoteManager voteManager) {
        //记录黑名单中,禁止登录系统
        System.out.println("进入黑名单,将禁止登录和使用本系统");
    }

}

Environmental category:

public class VoteManager {
    //持有状体处理对象
    private VoteState state = null;
    //记录用户投票的结果,Map<String,String>对应Map<用户名称,投票的选项>
    private Map<String,String> mapVote = new HashMap<String,String>();
    //记录用户投票次数,Map<String,Integer>对应Map<用户名称,投票的次数>
    private Map<String,Integer> mapVoteCount = new HashMap<String,Integer>();
    /**
     * 获取用户投票结果的Map
     */
    public Map<String, String> getMapVote() {
        return mapVote;
    }
    /**
     * 投票
     * @param user    投票人
     * @param voteItem    投票的选项
     */
    public void vote(String user,String voteItem){
        //1.为该用户增加投票次数
        //从记录中取出该用户已有的投票次数
        Integer oldVoteCount = mapVoteCount.get(user);
        if(oldVoteCount == null){
            oldVoteCount = 0;
        }
        oldVoteCount += 1;
        mapVoteCount.put(user, oldVoteCount);
        //2.判断该用户的投票类型,就相当于判断对应的状态
        //到底是正常投票、重复投票、恶意投票还是上黑名单的状态
        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);
    }
}

Client class:

public class Client {

    public static void main(String[] args) {
        
        VoteManager vm = new VoteManager();
        for(int i=0;i<9;i++){
            vm.vote("u1","A");
        }
    }

}

 

Guess you like

Origin blog.csdn.net/sinat_37138973/article/details/88635502