博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
10、State 状态模式
阅读量:4098 次
发布时间:2019-05-25

本文共 5119 字,大约阅读时间需要 17 分钟。

当对象的状态改变时,同时改变其行为,很好理解!就拿QQ来说,有几种状态,在线、隐身、忙碌等,每个状态对应不同的操作,而且你的好友也能看到你的状态,所以,状态模式就两点:1、可以通过改变状态来获得不同的行为。2、你的好友能同时看到你的变化。

状态模式允许一个对象在其内部状态改变的时候改变其行为。这个对象看上去就像是改变了它的类一样。

类图

State类是个状态类,Context类可以实现切换。

代码示例

State类:

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类:

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.	}  

测试类:

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.	}  

根据这个特性,状态模式在日常开发中用的挺多的,尤其是做网站的时候,我们有时希望根据对象的某一属性,区别开他们的一些功能,比如说简单的权限控制等。

状态模式的结构

用一句话来表述,状态模式把所研究的对象的行为包装在不同的状态对象里,每一个状态对象都属于一个抽象状态类的一个子类。状态模式的意图是让一个对象在其内部状态改变的时候,其行为也随之改变。

状态模式所涉及到的角色有:

  ●环境(Context)角色,也成上下文:定义客户端所感兴趣的接口,并且保留一个具体状态类的实例。这个具体状态类的实例给出此环境对象的现有状态。

  ●抽象状态(State)角色:定义一个接口,用以封装环境(Context)对象的一个特定的状态所对应的行为。

  ●具体状态(ConcreteState)角色:每一个具体状态类都实现了环境(Context)的一个状态所对应的行为。

应用场景

考虑一个在线投票系统的应用,要实现控制同一个用户只能投一票,如果一个用户反复投票,而且投票次数超过5次,则判定为恶意刷票,要取消该用户投票的资格,当然同时也要取消他所投的票;如果一个用户的投票次数超过8次,将进入黑名单,禁止再登录和使用系统。

要使用状态模式实现,首先需要把投票过程的各种状态定义出来,根据以上描述大致分为四种状态:正常投票、反复投票、恶意刷票、进入黑名单。然后创建一个投票管理对象(相当于Context)。

 

抽象状态类

 

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

具体状态类--正常投票

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

具体状态类--重复投票

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

具体状态类--恶意刷票

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("你有恶意刷屏行为,取消投票资格");    }}

具体状态类--黑名单

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

环境类:

public class VoteManager {    //持有状体处理对象    private VoteState state = null;    //记录用户投票的结果,Map
对应Map
<用户名称,投票的选项>
private Map
mapVote = new HashMap
(); //记录用户投票次数,Map
对应Map
<用户名称,投票的次数>
private Map
mapVoteCount = new HashMap
(); /** * 获取用户投票结果的Map */ public Map
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); }}

客户端类:

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

 

转载地址:http://uxrii.baihongyu.com/

你可能感兴趣的文章
configure: error: Please reinstall the BZip2 distribution
查看>>
OpenCV gpu模块样例注释:video_reader.cpp
查看>>
【增强学习在无人驾驶中的应用】
查看>>
《python+opencv实践》四、图像特征提取与描述——29理解图像特征
查看>>
《python+opencv实践》四、图像特征提取与描述——30Harris 角点检测
查看>>
《python+opencv实践》四、图像特征提取与描述——31 Shi-Tomasi 角点检测& 适合于跟踪的图像特征
查看>>
OpenCV meanshift目标跟踪总结
查看>>
人工神经网络——神经元模型介绍
查看>>
人工神经网络——感知器介绍
查看>>
人工神经网络——反向传播算法(BackPropagation)
查看>>
进程的地址空间概述
查看>>
Windows 窗口底层原理
查看>>
一种函数指针的运用
查看>>
Win32程序之进程的原理
查看>>
C++虚函数原理
查看>>
MySQL的索引
查看>>
今天,Python信息量很大!
查看>>
Flash 已死,Deno 当立?
查看>>
编程差的程序员,90%都是吃了数学的亏!骨灰级开发:方法不对,努力也白费...
查看>>
编程差的程序员,90%都是吃了数学的亏!骨灰级开发:方法不对,努力也白费...
查看>>