模式定义:
模式结构:
模式实现:
public class StatePattern {
@Test
public void testState() {
Fish fish = new Fish();
fish.hurt();
fish.cure();
fish.cure();
fish.hurt();
fish.hurt();
fish.hurt();
fish.rebirth();
}
/**
* 小鱼人
*/
class Fish {
/**
* 当前状态,当前血量
*/
private IState cur;
private int blood;
/**
* 四种状态
*/
private IState death;
private IState rebirth;
private IState hurt;
private IState cure;
public Fish() {
death = new Death(this);
rebirth = new Rebirth(this);
hurt = new Hurt(this);
cure = new Cure(this);
//默认状态为 满血复活状态
cur = rebirth;
blood = 100;
}
public int getBlood() {
return blood;
}
public void setBlood(int blood) {
this.blood = blood;
}
public IState getCur() {
return cur;
}
public void setCur(IState cur) {
this.cur = cur;
}
public IState getCure() {
return cure;
}
public void setCure(IState cure) {
this.cure = cure;
}
public IState getDeath() {
return death;
}
public void setDeath(IState death) {
this.death = death;
}
public IState getHurt() {
return hurt;
}
public void setHurt(IState hurt) {
this.hurt = hurt;
}
public IState getRebirth() {
return rebirth;
}
public void setRebirth(IState rebirth) {
this.rebirth = rebirth;
}
public void hurt() {
cur.hurt();
}
public void cure() {
cur.cure();
}
public void rebirth() {
cur.rebirth();
}
}
class Death implements IState {
private Fish fish;
public Death(Fish fish) {
this.fish = fish;
}
@Override
public void rebirth() {
fish.setCur(fish.getRebirth());
fish.setBlood(100);
System.out.println("you are rebirth, current blood is " + fish.getBlood() + ". \n");
}
@Override
public void hurt() {
System.out.println("you are death, can't be hurt");
}
@Override
public void cure() {
System.out.println("you are death, can't be cured");
}
}
class Rebirth implements IState {
private Fish fish;
public Rebirth(Fish fish) {
this.fish = fish;
}
@Override
public void rebirth() {
System.out.println("you have rebirth, no rebirth again");
}
@Override
public void hurt() {
if (fish.getBlood() > 50) {
fish.setCur(fish.getHurt());
fish.setBlood(fish.getBlood() - 50);
System.out.println("you have been hurt, current blood is " + fish.getBlood() + ". \n");
} else {
fish.setCur(fish.death);
fish.setBlood(0);
System.out.println("you have been hurt to death, current blood is " + fish.getBlood() + ". \n");
}
}
@Override
public void cure() {
System.out.println("you have rebirth, no need cure");
}
}
class Hurt implements IState {
private Fish fish;
public Hurt(Fish fish) {
this.fish = fish;
}
@Override
public void rebirth() {
System.out.println("you are hurt, no rebirth");
}
@Override
public void hurt() {
if (fish.getBlood() > 50) {
fish.setCur(fish.getHurt());
fish.setBlood(fish.getBlood() - 50);
System.out.println("you have been hurt, current blood is " + fish.getBlood() + ". \n");
} else {
fish.setCur(fish.death);
fish.setBlood(0);
System.out.println("you have been hurt to death, current blood is " + fish.getBlood() + ". \n");
}
}
@Override
public void cure() {
fish.setCur(fish.getCure());
fish.setBlood(fish.getBlood() + 50 > 100 ? 100 : fish.getBlood() + 50);
System.out.println("you have been cured, current blood is " + fish.getBlood() + ". \n");
}
}
class Cure implements IState {
private Fish fish;
public Cure(Fish fish) {
this.fish = fish;
}
@Override
public void rebirth() {
System.out.println("you are cure, no rebirth");
}
@Override
public void hurt() {
fish.setCur(fish.getHurt());
fish.setBlood(fish.getBlood() - 50);
System.out.println("you have been hurt, current blood is " + fish.getBlood() + ". \n");
}
@Override
public void cure() {
fish.setCur(fish.getCure());
fish.setBlood(fish.getBlood() + 50 > 100 ? 100 : fish.getBlood() + 50);
System.out.println("you have been cured, current blood is " + fish.getBlood() + ". \n");
}
}
/**
* LOL英雄状态
*/
interface IState {
/**
* 重生
*/
void rebirth();
/**
* 受伤
*/
void hurt();
/**
* 治疗
*/
void cure();
}
}
模式优点:
1、封装了转换规则
2、将所有与某个状态有关的行为放到一个类中,并且可以方便地增加新的状态,只需要改变对象状态即可改变对象的行为
3、允许状态转换逻辑与状态对象合成一体,而不是某一个巨大的条件语句块
4、可以让多个环境对象共享一个状态对象,从而减少系统中对象的个数
模式缺点:
1、状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱
2、状态模式对“开闭原则”的支持并不太好,对于可以切换状态的状态模式,增加新的状态类需要修改那些负责状态转换的源代码,否则无法切换到新增状态;而且修改某个状态类的行为也需修改对应类的源代码
适用场景:
1、对象的行为依赖于它的状态(属性)并且可以根据它的状态改变而改变它的相关行为
2、代码中包含大量与对象状态有关的条件语句