设计模式❤状态机模式

2018-02-27  本文已影响0人  miyakee

状态模式把所研究的对象的行为包装在不同的状态对象里,每一个状态对象都属于一个抽象状态类的一个子类。通过改变对象内部的状态,使得你可以在运行时动态改变一个对象的行为。

状态模式的示意性类图

首先我们设定一个奥特曼的接口

 interface Ultraman {

    void attackMonster();

    void shapeShift();

    void shooting();

    void usePower();
}

这个奥特曼有3种状态:

/**人类状态**/
public class personState implements Ultraman {
    private Context context;


      personState(Context context){
        System.out.println("我是一个人 !!");
        this.context=context;
    }

    @Override
    public void attackMonster(){
        System.out.println("人类打不赢怪兽,快变身吧");

    }

    @Override
    public void shapeShift(){
        System.out.println("变成奥特曼了");
        context.setState(context.becomeUltraman());
    }

    @Override
    public void shooting(){
        System.out.println("射击!!");

    }


    @Override
    public void usePower() {

    //do nothing
    }
   }

/**力量用完的状态**/
class powerOffState implements Ultraman {
    private Context context;

    powerOffState(Context context) {
        this.context = context;

    }

    @Override
    public void attackMonster() {

    }

    @Override
    public void shapeShift() {
        System.out.println("变成人了");
        context.setState(context.becomePeople());
    }

    @Override
    public void shooting() {
        System.out.println("手太大,射击技能不能使用");
    }


    @Override
    public void usePower() {
        System.out.println("能量用完了");
    }
}

/**正常奥特曼状态**/
public class ultramanState implements Ultraman {
    private Context context;

    ultramanState(Context context) {
        this.context = context;
    }

    @Override
    public void attackMonster() {
        System.out.println("攻击小怪兽");
        context.resultMonster();

    }

    @Override
    public void shapeShift() {
        System.out.println("变成人了");
        context.setState(context.becomePeople());
    }

    @Override
    public void shooting() {
        System.out.print("手太大,射击技能不能使用");
    }


    @Override
    public void usePower() {
        System.out.println("消耗能量一颗");
    }

}

这是一个环境角色部分,定义用户需要或者说感兴趣的接口

public class Context {

    private Ultraman personState;
    private Ultraman powerOffState;
    private Ultraman ultramanState;
    private Ultraman ultraman;
    private int powerValue;


    public Context() {
        this.personState = new personState(this);
        this.powerOffState = new powerOffState(this);
        this.ultramanState = new ultramanState(this);
        this.ultraman = personState;
    }

    //设置当前处于的状态
     void setState(Ultraman ultraman) {

        this.ultraman = ultraman;
    }


    //变身  变身前初始化能量
    public void shapeShift(int powerValue) {
        this.powerValue = powerValue;
        ultraman.shapeShift();

    }

    //变成人
      Ultraman becomePeople() {
        return personState;
    }

    //变成怪兽
      Ultraman becomeUltraman() {

        return ultramanState;
    }

    //打怪兽的结果
     void resultMonster() {

        if (powerValue > 0) { //能量没有用完
            ultraman.usePower();
            System.out.println("哈哈哈 恭喜击败小怪兽1只");
            powerValue--;
        } else {
            //能量用完转化成能量用完状态
            this.setState(powerOffState);
            ultraman.usePower();
            System.out.println("你被小怪兽击败了");

        }
    }


    //攻击怪兽
    public void battle() {
        ultraman.attackMonster();

    }

    //射击
    public void shooting() {
        ultraman.shooting();
    }


}

实际调用部分

public class battleTest {
    public static  void  main(String[] args){
         int powerValue=1;              //初始化奥特曼的能量为5
        Context context=new Context();
        System.out.println("怪兽出现了0口0");
        context.shooting();             //人类可以射击
        context.battle();             //人类可以射击
        context.shapeShift(powerValue); //射击不成功,变身
        for(int i=0;i<1;i++){           //出现了四只怪兽,打败了所有怪兽
        context.battle();
        }
        context.shapeShift(powerValue);  //打完怪兽,变回人
        context.shooting();              //人类可以射击
        context.shapeShift(powerValue);   //又变成怪兽
        for(int i=0;i<2;i++){             //出现了六只怪兽,被打败
            context.battle();
        }
    }

}

和策略模式存在的区别:【自己切换和主动切换】
状态模式将各个状态所对应的操作分离开来,即对于不同的状态,由不同的子类实现具体操作,不同状态的切换由子类实现,当发现传入参数不是自己这个状态所对应的参数,则自己给Context类切换状态;而策略模式是直接依赖注入到Context类的参数进行选择策略,不存在切换状态的操作练习。

在jdk里的应用:

java.util.Iterator
javax.faces.lifecycle.LifeCycle#execute()

参考:http://blog.csdn.net/seacean2000/article/details/10528153

上一篇下一篇

猜你喜欢

热点阅读