状态模式
状态模式(State):当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。
这句话我理解起来就是就相当于一个宅男,理了个发穿了个时髦的衣服整个形象都变了,就会给人一种感觉像是变了一个人一样。
上次的用的是游戏的例子,这次也用游戏,谁让游戏人物到处都是状态。
就好比说等级吧!游戏里面有升级,同样的死亡也有惩罚,当到达一定程度的时候还可能会降级,而随着升降级,人物的基本属性攻魔防等状态也会随之变化。
把每一级的基本属性都看成一个模版,升降级就换模版上去,然后给模版定一个公共接口方便转换。
代码实现
//首先是人物角色
class Role{
//状态
private State state;
public Role(State state){
this.state=state;
}
//升级
public void upgrade(){
state.next(this);;
}
//降级
public void retrogress(){
state.last(this);;
}
//查看属性
public void display(){
state.display(state);
}
public void setState(State state) {
this.state = state;
}
}
//状态接口
interface State{
void last(Role role);
void next(Role role);
void display(State state);
}
//等级一状态,后面以此类推,为了省事儿就不再额外添加攻魔防属性了
class One implements State{
@Override
public void last(Role role) {
role.setState(this);
}
@Override
public void next(Role role) {
role.setState( new Two());
}
@Override
public void display(State state) {
System.out.println("一级");
}
}
class Two implements State{
@Override
public void last(Role role) {
role.setState(new One());
}
@Override
public void next(Role role) {
role.setState(new Three());
}
@Override
public void display(State state) {
System.out.println("二级");
}
}
class Three implements State{
@Override
public void last(Role role) {
role.setState(new Two());
}
@Override
public void next(Role role) {
role.setState(this);
}
@Override
public void display(State state) {
System.out.println("三级");
}
}
public class Client {
public static void main(String[] args) {
//人物初始属性
Role role=new Role(new One());
role.display();
//升级
role.upgrade();
role.display();
//降级
role.retrogress();
role.display();
//连升两级
role.upgrade();
role.upgrade();
role.display();
}
}
输出
一级
二级
一级
三级
状态模式组成
环境类(Context):可以包括一些内部状态。 好比我们的角色
抽象状态类(State):State定义了一个所有具体状态的共同接口,任何状态都实现这个相同的接口,这样一来,状态之间就可以互相转换了。
具体状态类(ConcreteState):用于处理来自Context的请求,每一个ConcreteState都提供了它对自己请求的实现,所以,当Context改变状态时行为也会跟着改变。就是我们的等级模版啦!
适用情况
状态模式在实际使用中比较多,适合”状态的切换”。因为我们经常会使用If elseif else 进行状态切换, 如果针对状态的这样判断切换反复出现,我们就要联想到是否可以采取State模式了。
也可以根据属性。如果某个对象的属性不同,对象的行为就不一样,这种属性的改变(切换)又是随时可能发生的,就有可能要使用State。