设计模式❤状态机模式

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

状态模式的示意性类图

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

 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

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,969评论 19 139
  • 《JavaScript设计模式与开发实践》作者:曾探 系统的介绍了各种模式,以及js中的实现、应用,以及超大量高质...
    undefinedR阅读 837评论 0 10
  • 设计模式汇总 一、基础知识 1. 设计模式概述 定义:设计模式(Design Pattern)是一套被反复使用、多...
    MinoyJet阅读 3,979评论 1 15
  • 设计模式基本原则 开放-封闭原则(OCP),是说软件实体(类、模块、函数等等)应该可以拓展,但是不可修改。开-闭原...
    西山薄凉阅读 3,880评论 3 14
  • 在所有过去和将来,所有值得怀念与值得期待的景色里,依然还是你。 赋诗一首,情怀依旧: 《在蝉鸣的夏夜》 我左手提瓜...
    春风小小僧阅读 281评论 1 1