zoukankan      html  css  js  c++  java
  • 状态模式-State

    状态模式也称状态机(State Machine),简单用一句话解释就是:用对象定义具体状态,调用时指向具体状态对象的方法。

    一、类图

    状态模式包含以下主要角色。

    • 环境(Context)角色:也称为上下文,它定义了客户感兴趣的接口,维护一个当前状态,并将与状态相关的操作委托给当前状态对象来处理。
    • 抽象状态(State)角色:定义一个接口,用以封装环境对象中的特定状态所对应的行为。
    • 具体状态(Concrete    State)角色:实现抽象状态所对应的行为。

    二、示例

    用“状态模式”设计一个学生成绩的状态转换程序。包含了“不及格”“中等”和“优秀” 3 种状态,当学生的分数小于 60 分时为“不及格”状态,当分数大于等于 60 分且小于 90 分时为“中等”状态,当分数大于等于 90 分时为“优秀”状态,我们用状态模式来实现这个程序。

    package state;
    public class ScoreStateTest
    {
        public static void main(String[] args)
        {
            ScoreContext account=new ScoreContext();
            System.out.println("学生成绩状态测试:");
            account.add(30);
            account.add(40);
            account.add(45);
            account.add(-35);
            account.add(-25);
        }
    }
    //环境类
    class ScoreContext
    {
        private AbstractState state;
        ScoreContext()
        {
            state=new LowState(this);
        }
        public void setState(AbstractState state)
        {
            this.state=state;
        }
        public AbstractState getState()
        {
            return state;
        }   
        public void add(int score)
        {
            state.addScore(score);
        }
    }
    //抽象状态类
    abstract class AbstractState
    {
        protected ScoreContext hj;  //环境
        protected String stateName; //状态名
        protected int score; //分数
        public abstract void checkState(); //检查当前状态
        public void addScore(int x)
        {
            score+=x;       
            System.out.print("加上:"+x+"分,	当前分数:"+score );
            checkState();
            System.out.println("分,	当前状态:"+hj.getState().stateName);
        }   
    }
    //具体状态类:不及格
    class LowState extends AbstractState
    {
        public LowState(ScoreContext h)
        {
            hj=h;
            stateName="不及格";
            score=0;
        }
        public LowState(AbstractState state)
        {
            hj=state.hj;
            stateName="不及格";
            score=state.score;
        }
        public void checkState()
        {
            if(score>=90)
            {
                hj.setState(new HighState(this));
            }
            else if(score>=60)
            {
                hj.setState(new MiddleState(this));
            }
        }   
    }
    //具体状态类:中等
    class MiddleState extends AbstractState
    {
        public MiddleState(AbstractState state)
        {
            hj=state.hj;
            stateName="中等";
            score=state.score;
        }
        public void checkState()
        {
            if(score<60)
            {
                hj.setState(new LowState(this));
            }
            else if(score>=90)
            {
                hj.setState(new HighState(this));
            }
        }
    }
    //具体状态类:优秀
    class HighState extends AbstractState
    {
        public HighState(AbstractState state)
        {
            hj=state.hj;
            stateName="优秀";
            score=state.score;
        }           
        public void checkState()
        {
            if(score<60)
            {
                hj.setState(new LowState(this));
            }
            else if(score<90)
            {
                hj.setState(new MiddleState(this));
            }
        }
    }

    三、优缺点

    优点:

    封装了转换规则。枚举可能的状态,在枚举状态之前需要确定状态种类。
    将所有与某个状态有关的行为放到一个类中,并且可以方便地增加新的状态,只需要改变对象状态即可改变对象的行为。
    允许状态转换逻辑与状态对象合成一体,而不是某一个巨大的条件语句块。
    可以让多个环境对象共享一个状态对象,从而减少系统中对象的个数。

    缺点:

    状态模式的使用必然会增加系统类和对象的个数。
    状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱。
    状态模式对“开闭原则”的支持并不太好,对于可以切换状态的状态模式,增加新的状态类需要修改那些负责状态转换的源代码,否则无法切换到新增状态;而且修改某个状态类的行为也需修改对应类的源代码。

    ……更多设计模式的内容,可以访问Refactoring.Guru

  • 相关阅读:
    Jquery简略API使用
    JS全部API笔记
    实现nginx的负载均衡和反向代理
    HashMap在Java1.7与1.8中的区别
    数据库设计三大范式
    Java集合
    Object类有哪些方法
    spring mvc出现 Failed to convert property value of type 'java.lang.String' to required type 'java.util.Date' for property 'endtime'
    int和Integer的区别
    第二次面试-科大讯飞(卒)
  • 原文地址:https://www.cnblogs.com/rouqinglangzi/p/11760840.html
Copyright © 2011-2022 走看看