《JAVA设计模式》之状态模式(State)
在阎宏博士的《JAVA与模式》一书中开头是这样描述状态(State)模式的:
状态模式,又称状态对象模式(Pattern of Objects for States),状态模式是对象的行为模式。
状态模式允许一个对象在其内部状态改变的时候改变其行为。这个对象看上去就像是改变了它的类一样。
状态模式的结构
用一句话来表述,状态模式把所研究的对象的行为包装在不同的状态对象里,每一个状态对象都属于一个抽象状态类的一个子类。状态模式的意图是让一个对象在其内部状态改变的时候,其行为也随之改变。状态模式的示意性类图如下所示:
状态模式所涉及到的角色有:
● 环境(Context)角色,也成上下文:定义客户端所感兴趣的接口,并且保留一个具体状态类的实例。这个具体状态类的实例给出此环境对象的现有状态。
● 抽象状态(State)角色:定义一个接口,用以封装环境(Context)对象的一个特定的状态所对应的行为。
● 具体状态(ConcreteState)角色:每一个具体状态类都实现了环境(Context)的一个状态所对应的行为。
源代码
环境角色类
public class Context {
//持有一个State类型的对象实例
private State state; public void setState(State state) {
this.state = state;
}
/**
* 用户感兴趣的接口方法
*/
public void request(String sampleParameter) {
//转调state来处理
state.handle(sampleParameter);
}
}
抽象状态类
public interface State {
/**
* 状态对应的处理
*/
public void handle(String sampleParameter);
}
具体状态类
public class ConcreteStateA implements State { @Override
public void handle(String sampleParameter) { System.out.println("ConcreteStateA handle :" + sampleParameter);
} }
public class ConcreteStateB implements State { @Override
public void handle(String sampleParameter) { System.out.println("ConcreteStateB handle :" + sampleParameter);
} }
客户端类
public class Client { public static void main(String[] args){
//创建状态
State state = new ConcreteStateB();
//创建环境
Context context = new Context();
//将状态设置到环境中
context.setState(state);
//请求
context.request("test");
}
}
从上面可以看出,环境类Context的行为request()是委派给某一个具体状态类的。通过使用多态性原则,可以动态改变环境类Context的属性State的内容,使其从指向一个具体状态类变换到指向另一个具体状态类,从而使环境类的行为request()由不同的具体状态类来执行。
使用场景
考虑一个在线投票系统的应用,要实现控制同一个用户只能投一票,如果一个用户反复投票,而且投票次数超过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<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);
}
}
客户端类
public class Client { public static void main(String[] args) { VoteManager vm = new VoteManager();
for(int i=0;i<9;i++){
vm.vote("u1","A");
}
} }
运行结果如下:
aaarticlea/png;base64,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" alt="" />
从上面的示例可以看出,状态的转换基本上都是内部行为,主要在状态模式内部来维护。比如对于投票的人员,任何时候他的操作都是投票,但是投票管理对象的处理却不一定一样,会根据投票的次数来判断状态,然后根据状态去选择不同的处理。
认识状态模式
● 状态和行为
所谓对象的状态,通常指的就是对象实例的属性的值;而行为指的就是对象的功能,再具体点说,行为大多可以对应到方法上。
状态模式的功能就是分离状态的行为,通过维护状态的变化,来调用不同状态对应的不同功能。也就是说,状态和行为是相关联的,它们的关系可以描述为:状态决定行为。
由于状态是在运行期被改变的,因此行为也会在运行期根据状态的改变而改变。
● 行为的平行性
注意平行线而不是平等性。所谓平行性指的是各个状态的行为所处的层次是一样的,相互独立的、没有关联的,是根据不同的状态来决定到底走平行线的哪一条。行为是不同的,当然对应的实现也是不同的,相互之间是不可替换的。
而平等性强调的是可替换性,大家是同一行为的不同描述或实现,因此在同一个行为发生的时候,可以根据条件挑选任意一个实现来进行相应的处理。
大家可能会发现状态模式的结构和策略模式的结构完全一样,但是,它们的目的、实现、本质却是完全不一样的。还有行为之间的特性也是状态模式和策略模式一个很重要的区别,状态模式的行为是平行性的,不可相互替换的;而策略模式的行为是平等性的,是可以相互替换的。
● 环境和状态处理对象
在状态模式中,环境(Context)是持有状态的对象,但是环境(Context)自身并不处理跟状态相关的行为,而是把处理状态的功能委托给了状态对应的状态处理类来处理。
在具体的状态处理类中经常需要获取环境(Context)自身的数据,甚至在必要的时候会回调环境(Context)的方法,因此,通常将环境(Context)自身当作一个参数传递给具体的状态处理类。
客户端一般只和环境(Context)交互。客户端可以用状态对象来配置一个环境(Context),一旦配置完毕,就不再需要和状态对象打交道了。客户端通常不负责运行期间状态的维护,也不负责决定后续到底使用哪一个具体的状态处理对象。
原文地址:《JAVA与模式》之状态模式
《JAVA设计模式》之状态模式(State)的更多相关文章
- 折腾Java设计模式之状态模式
原文地址 折腾Java设计模式之状态模式 状态模式 在状态模式(State Pattern)中,类的行为是基于它的状态改变的.这种类型的设计模式属于行为型模式.在状态模式中,我们创建表示各种状态的对象 ...
- 【转】设计模式 ( 十七) 状态模式State(对象行为型)
设计模式 ( 十七) 状态模式State(对象行为型) 1.概述 在软件开发过程中,应用程序可能会根据不同的情况作出不同的处理.最直接的解决方案是将这些所有可能发生的情况全都考虑到.然后使用if... ...
- 设计模式 ( 十七) 状态模式State(对象行为型)
设计模式 ( 十七) 状态模式State(对象行为型) 1.概述 在软件开发过程中,应用程序可能会根据不同的情况作出不同的处理.最直接的解决方案是将这些所有可能发生的情况全都考虑到.然后使用if... ...
- 乐在其中设计模式(C#) - 状态模式(State Pattern)
原文:乐在其中设计模式(C#) - 状态模式(State Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 状态模式(State Pattern) 作者:webabcd 介绍 允 ...
- 北风设计模式课程---状态模式State(对象行为型)
北风设计模式课程---状态模式State(对象行为型) 一.总结 一句话总结: 状态模式 具体状态的行为在具体的状态类中就解决,不用交给外部做判断.实质是将多条件判断弄成了多个类,在不同的类中做判断 ...
- 二十四种设计模式:状态模式(State Pattern)
状态模式(State Pattern) 介绍允许一个对象在其内部状态改变时改变它的行为.对象看起来似乎修改了它所属的类. 示例有一个Message实体类,对它的操作有Insert()和Get()方法, ...
- 设计模式2——状态模式State
参考链接: 设计模式之状态模式:https://www.cnblogs.com/haoerlv/p/7777789.html 设计模式系列之状态模式:https://www.jianshu.com/p ...
- 设计模式之 -- 状态模式(State)
状态模式允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类.当控制一个对象的状态转换条件分支语句(if...else或switch...case)过于复杂时,可以此模式将状态的判断逻辑 ...
- [设计模式] 20 状态模式 State Pattern
在GOF的<设计模式:可复用面向对象软件的基础>一书中对状态模式是这样说的:允许一个对象在其内部状态改变时改变它的行为.对象看起来似乎修改了它的类.状态模式的重点在于状态转换,很多时候,对 ...
- JAVA设计模式:状态模式
声明:转载请说明来源:http://www.cnblogs.com/pony1223/p/7518226.html 一.引出状态模式 假设我们现在有一个糖果机项目,那么我们知道正常一般糖果机提供给用户 ...
随机推荐
- 分布式唯一ID生成器
在应用程序中,经常需要全局唯一的ID作为数据库主键.如何生成全局唯一ID? 首先,需要确定全局唯一ID是整型还是字符串?如果是字符串,那么现有的UUID就完全满足需求,不需要额外的工作.缺点是字符串作 ...
- web前端工程化
目标 1.能够了解模块化的相关规范 2.了解webpack 3.了解使用Vue单文件组件 4.能够搭建Vue脚手架 5.掌握Element-UI的使用 1.模块化的分类 A.浏览器端的模块化 1).A ...
- JavaScript、ES6中的类和对象
面向对象可以用于描述现实世界的事物,但是事物分为具体的(特指的)事物和抽象的(泛指的)事物. 面向对象思维的特点: 1.抽取(抽象)对象共有的属性和行为组织(封装)成一个类(模板) 2. ...
- html a标签链接点击闪动问题解决
<a href="#">链接点击会闪动,解决: 这三种都可以用:<a href="javascript:;"></a>< ...
- nginx 实现浏览器文件下载服务
nginx 实现浏览器文件下载服务 2018/07/21 这里记录如何用 nginx 搭建一个简易的 file server,实现在浏览器上进行文件的下载操作. 要实现文件下载功能非常非常容易,不需要 ...
- Mac sublime 安装包的时候出现 unable to download xxx (_ssl.c:548)
Mac sublime 安装包的时候出现 unable to download xxx前置条件:[本文行文中,所使用的电脑环境为 mac](当然不排除,在其他系统下,依然可以采用这种解决方案) 今天想 ...
- js实时计算价格
//通过数量,单价的输入,实时显示总价 $("#number,#price").on("input",function(e){ $("#totalPr ...
- 2018-08-01-weekly
Algorithm 4. Median of Two Sorted Arrays What 两个排序数组的中位数 How 两个数组合并到同一个数组,然后进行排序取中间值即可 Key Codes cla ...
- 持续优化云原生体验,阿里云在Serverless容器与多云上的探索
近日,阿里云宣布推出Serverless Kubernetes服务此举意在降低容器技术的使用门槛.简化容器平台运维.并同时发布阿里云服务对Open Service Broker API标准支持,通过一 ...
- BZOJ 2286: [Sdoi2011]消耗战 虚树
Description 在一场战争中,战场由n个岛屿和n-1个桥梁组成,保证每两个岛屿间有且仅有一条路径可达.现在,我军已经侦查到敌军的总部在编号为1的岛屿,而且他们已经没有足够多的能源维系战斗,我军 ...