实例探索Java模式之路——状态模式

状态模式


1、状态模式是对象的行为模式。
状态模式允许一个对象在内部状态改变的时候改变其行为。这个对象看上去就像是改变了它的类一样。
一个对象的行为取决于一个或多个动态变化的属性,这样的属性叫做状态,这样的对象叫做有状态的对象。


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


3、状态模式结构:


抽象状态:用以封装环境对象的一个特定的状态所对应的行为。
具体状态:每一个具体状态都实现了环境的一个状态锁对应的行为。
环境角色:定义客户端感兴趣的接口,并保留一个具体状态类的实例。这个具体状态类的实例给出此环境对象现有的状态。


环境类是所考察的类,而它的行为是委派给类型为State的一个对象的。由于State本身是一个抽象类或接口,实际担当此任务的是具体状态类。
环境类的行为是委派给一个具体状态类的。
多态性原则,可以动态地改变环境类的属性State的内容,使其从指向一个具体状态类变换到指向另一个具体状态类,从而是环境类的行为由不同的具体状态类来执行。


4、简单实例
//抽象状态角色
public interface State {
void sampleOperation();
}


//具体状态角色
public class ConcreteState1 implements State {


@Override
public void sampleOperation() {
System.out.println("具体状态角色1");
}




}


//具体状态角色
public class ConcreteState2 implements State {


@Override
public void sampleOperation() {
System.out.println("具体状态角色2");
}
}


//环境类角色
public class Context {
private State state;// 持有State对象,并把行为委派给此对象


public void sampleOperation() {
state.sampleOperation();
}


public void setState(State state) {
this.state = state;
}


}


//客户端,创建具体命令对象并确定其接受者
public class Client {


public static void main(String[] args) {


Context context = new Context();
State state = new ConcreteState3();
context.setState(state);
context.sampleOperation();


int flag = 3;


// 状态模式用意是当状态发生变化,自动调换实现类
if (flag == 1) {
state = new ConcreteState1();
context.setState(state);
context.sampleOperation();
} else if (flag == 2) {
state = new ConcreteState2();
context.setState(state);
context.sampleOperation();
} else if (flag == 3) {
state = new ConcreteState3();
context.setState(state);
context.sampleOperation();
}
}


}


5、一个模拟投票的例子(根据用户投票次数做出相应的动作或行为)


//抽象状态角色,投票的例子
public interface VoteState {
public void vote(String voteuser, String voteItem, VoteManage votemanage);
}
//正常投票
public class NormalVote implements VoteState {


@Override
public void vote(String voteuser, String voteItem, VoteManage votemanage) {


votemanage.getVoteMap().put(voteuser, voteItem);
System.out.println("投票成功!");
}


}
//重复投票
public class RepeatVote implements VoteState {


@Override
public void vote(String voteuser, String voteItem, VoteManage votemanage) {
System.out.println("重复投票!");
}


}
//恶意刷票
public class SpiteVote implements VoteState {


@Override
public void vote(String voteuser, String voteItem, VoteManage votemanage) {
String str=votemanage.getVoteMap().get(voteuser);
if (str!=null) {
votemanage.getVoteMap().remove(voteuser);
}
System.out.println("恶意刷票,取消投票资格");


}


}
//判定恶意刷票再进行投票则被系统拉黑
public class BlackVote implements VoteState {


@Override
public void vote(String voteuser, String voteItem, VoteManage votemanage) {
System.out.println("进入黑名单,禁止登录");


}


}


import java.util.HashMap;
import java.util.Map;


//投票管理类,用于管理用户投票,每个用户每一种投票只能进行一次投票
public class VoteManage {
private VoteState voteState = null;
private Map<String, String> voteMap = new HashMap<String, String>();
private Map<String, Integer> voteCountMap = new HashMap<String, Integer>();


public Map<String, String> getVoteMap() {


return voteMap;


}


// 状态模式实现的精髓所在,判定用户行为,做出相应动作
public void Vote(String voteuser, String voteItem) {


Integer oldVoteInteger = voteCountMap.get(voteuser);
if (oldVoteInteger == null) {
oldVoteInteger = 0;
}
oldVoteInteger += 1;
voteCountMap.put(voteuser, oldVoteInteger);
if (oldVoteInteger == 1) {
voteState = new NormalVote();
} else if (oldVoteInteger > 1 && oldVoteInteger < 5) {
voteState = new RepeatVote();
} else if (oldVoteInteger >= 5 && oldVoteInteger < 8) {
voteState = new SpiteVote();
} else if (oldVoteInteger > 8) {
voteState = new BlackVote();
}


// 调状态对象进行相应的操作
voteState.vote(voteuser, voteItem, this);
}
}


//客户端,模拟用户多次投票
public class Client {


public static void main(String[] args) {


VoteManage vmcontext = new VoteManage();
for (int i = 0; i < 9; i++) {
vmcontext.Vote("A1", "B");
}
}


}


5、状态模式适用场景:
1、对象的行为依赖于它的状态(属性)并且可以根据它的状态改变而改变它的相关行为。 
2、代码中包含大量与对象状态有关的条件语句。

6、状态模式优缺点:
   优点:
  1、封装了转换规则。 
  2、枚举可能的状态,在枚举状态之前需要确定状态种类。 
  3、将所有与某个状态有关的行为放到一个类中,并且可以方便地增加新的状态,只需要改变对象状态即可改变对象的行为。 
  4、允许状态转换逻辑与状态对象合成一体,而不是某一个巨大的条件语句块。 
  5、可以让多个环境对象共享一个状态对象,从而减少系统中对象的个数。
   缺点:
  1、状态模式的使用必然会增加系统类和对象的个数。 
  2、状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱。 
  3、状态模式对“开闭原则”的支持并不太好,对于可以切换状态的状态模式,增加新的状态类需要修改那些负责状态转换的源代码,否则无法切换到新增状态;而且修改某个状态类的行为也需修改对应类的源代码。


通过此实例,相信对该模式有了进一步的认识。

每天努力一点,每天都在进步。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

powerfuler

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值