1.18(设计模式)状态模式

状态模式:当对象状态改变时行为也随之改变,看起来就像是这个类发生了改变。html

首先对象有状态,行为由状态决定。ide

 

假设如今有一个游戏角色,有正常状态、加速状态、减速状态、眩晕状态。this

游戏角色不一样状态下的行为是不一样的,减速跑的慢一些、眩晕不能跑。spa

咱们将游戏角色转换为代码,先看不使用状态模式的状况。code

 

游戏角色类htm

public class Hero {
public static final int COMMON = 1;//正常状态
    
    public static final int SPEED_UP = 2;//加速状态
    
    public static final int SPEED_DOWN = 3;//减速状态
    
    public static final int SWIM = 4;//眩晕状态
    
    private int state = COMMON;//默认是正常状态

    public int getState() {
        return state;
    }

    public void setState(int state) {
        this.state = state;
    }
    
    public void run() {
        if(state == COMMON) {
            System.out.println("正常状态");
        }else if(state == SPEED_UP) {
            System.out.println("加速状态");
        }
        else if(state == SPEED_DOWN) {
            System.out.println("减速状态");
        }
        else if(state == SWIM) {
            System.out.println("眩晕状态");
        }
    }
}

 

Main对象

public class Main {
    public static void main(String[] args) {
        //默认正常状态
        Hero hcf = new Hero();
        hcf.run();
        //加速状态
        hcf.setState(Hero.SPEED_UP);
        hcf.run();
        //眩晕状态
        hcf.setState(Hero.SWIM);
        hcf.run();
        //减速状态
        hcf.setState(Hero.SPEED_DOWN);
        hcf.run();
    }
}
运行结果:
正常状态
加速状态
眩晕状态
减速状态

 

游戏角色中有状态,执行run方法时会根据状态打印出不用的结果,即对象状态的改变也会形成行为的改变。blog

这样实现也能够,但若是后续分支状态过多,须要大量的if else,并且Hero的状态只对象Hero有效,怪兽一样有这些状态,接口

这些状态没法复用。游戏

 

 

这时咱们就能够采用状态模式

首先须要将状态抽取出来,每个状态对应一个状态类

 

状态接口

public interface State {
    public void change(Hero hero);
}

 

加速状态

public class SpeedUpState implements State {

    @Override
    public void change(Hero hero) {//传递英雄对象,改变英雄对象的状态
        // TODO Auto-generated method stub
        hero.setState(this);
    }

    @Override
    public String toString() {
        return "加速状态";
    }
    
    
}

 

减速状态

public class SpeedDownState implements State {

    @Override
    public void change(Hero hero) {//传递英雄对象,改变英雄对象的状态
        // TODO Auto-generated method stub
        hero.setState(this);
    }

    @Override
    public String toString() {
        return "减速状态";
    }
    
    
}

 

眩晕状态

public class SwimState implements State{
    @Override
    public void change(Hero hero) {//传递英雄对象,改变英雄对象的状态
        // TODO Auto-generated method stub
        hero.setState(this);
    }

    @Override
    public String toString() {
        return "眩晕状态";
    }
}

 

正常状态

public class CommonState implements State{
    @Override
    public void change(Hero hero) {//传递英雄对象,改变英雄对象的状态
        // TODO Auto-generated method stub
        hero.setState(this);
    }

    @Override
    public String toString() {
        return "正常状态";
    }
}

 

 

每个状态对应一个状态类,当英雄状态须要发送变化时,只需建立状态类,而后将heroz做为参数,调用状态类的change方法。

change方法会将当前状态对象设置到hero中的state属性,后续直接获取英雄状态便可。

 

Main

public class Main {
    public static void main(String[] args) {
        Hero hcf = new Hero();
        //正常状态
        CommonState commonState = new CommonState();
        commonState.change(hcf);
        System.out.println(hcf.getState().toString());
        
        //加速状态
        SpeedUpState speedUpState = new SpeedUpState();
        speedUpState.change(hcf);
        System.out.println(hcf.getState().toString());

        //眩晕状态
        SwimState swimState = new SwimState();
        swimState.change(hcf);
        System.out.println(hcf.getState().toString());

        //减速状态
        SpeedDownState speedDownState = new SpeedDownState();
        speedDownState.change(hcf);
        System.out.println(hcf.getState().toString());

    }
}
运行结果:
正常状态
加速状态
眩晕状态
减速状态

 

后续还有新的状态只需添加状态类便可,并且能够进一步抽象,使Heor类和怪兽类实现同一个接口,这样这些状态对于Hero和怪兽都适用。

 

 

参考资料:

https://www.runoob.com/design-pattern/state-pattern.html

https://www.cnblogs.com/zuoxiaolong/p/pattern22.html

相关文章
相关标签/搜索