设计模式:(状态模式)

1.定义

在状态模式(State Pattern)中,类的行为是基于它的状态改变的。这种类型的设计模式属于行为型模式。
在状态模式中,我们创建表示各种状态的对象和一个行为随着状态对象改变而改变的 context 对象。
简单来说:状态模式允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。

2.概述

一个对象的状态依赖于它的变量的取值情况,对象在不同的运行环境中,可能具有不同的状态。在许多情况下,对象调用方法所产生的行为效果依赖于它当时的状态。
状态模式的关键是将对象的状态封装成独立的类,对象(Context)调用方法时,可以委托当前对象所具有的状态(ConcreteState)调用相应的方法,使当前对象看起来好像修改了它的类。

3.应用场景

1、行为随状态改变而改变的场景。
2、条件、分支语句的代替者。
3、一个操作中含有庞大的多分支结构,并且这些分支决定于对象的状态。

4.模式的结构与使用

状态模式包括三种角色。
环境(Context): 环境是一个类,该类含有抽象状态(State)声明的变量,可以引用任何具体状态类的实例。用户对该环境(Context)类的实例在某种状态下的行为感兴趣。
抽象状态(State): 抽象状态是一个接口或抽象类。抽象状态中定义了与环境(Context)的一个特定状态相关的若干个方法。
具体状态(ConcreteState): 具体状态是实现(扩展)抽象状态(抽象类)的类。

1.状态模式的UML类图

在这里插入图片描述

2.结构的描述

以下通过一个简单的问题来描述怎样使用状态模式,这个简单的问题就是:设计带文字提示信息的温度计。带文字提示细腻的温度计可以根据用户的需求显示某些提示信息,比如用户希望温度在0度以下,显示提示信息为“低温温度”,温度在10-26度至今时,显示提示信息为“正常温度”,当温度在大于39度时,显示提示信息为“高温温度”。
1.抽象状态(State)
对于本问题,抽象状态(State)是TemperatureState接口,代码如下所示:
里面只有一个showTemperature()方法,可以显示具体温度的状态。

public interface TemperatureState {
    public void showTemperature();
}

2.具体状态(ConcreteState)
对于本问题,共有三个具体状态角色,分别是LowState,MiddleState和HeightState类,分别如下所示:
在里面定义一个默认的温度变量n,并实现了抽象状态的showTemperature()方法。
LowState.java

public class LowState implements TemperatureState{
    double n=0;
    public LowState(double n) {
        if(n<0)
        this.n = n;
    }
    @Override
    public void showTemperature() {
        System.out.println("现在的温度是"+n+"属于低温度");
    }
}

MiddleState.java

public class MiddleState implements TemperatureState{
    double n=15;
    public MiddleState(double n) {
        if(n>0 && n<26)
        this.n = n;
    }
    @Override
    public void showTemperature() {
        System.out.println("现在的温度"+n+"属于正常温度");
    }
}

HeightState.java

public class HeightState implements TemperatureState{
    double n=30;

    public HeightState(double n) {
        if(n>=39)
        this.n = n;
    }

    @Override
    public void showTemperature() {
        System.out.println("现在的温度"+n+"属于高温度");
    }
}

3.环境(Context)
本问题中,环境角色是Thermometer类,代码如下:
在该类中有抽象状态的类变量引用,并通过set方法设置当前具体状态,通过showTemperature()方法显示当前类变量state的温度情况。

public class Thermometer {
    TemperatureState state;
    public void  showMessage(){
        System.out.println("********");
        state.showTemperature();
        System.out.println("********");
    }

    public void setState(TemperatureState state){
        this.state=state;
    }
}

4.测试程序
Application.java

public class Application {
    public static void main(String[] args) {
        TemperatureState state=new LowState(-12);
        Thermometer thermometer=new Thermometer();//定义Context(上下文)
        thermometer.setState(state);
        thermometer.showMessage();

        //切换状态
        state=new MiddleState(20);
        thermometer.setState(state);
        thermometer.showMessage();

        //切换状态
        state=new HeightState(39);
        thermometer.setState(state);
        thermometer.showMessage();
    }
}

5.测试结果展示
在这里插入图片描述

5.状态模式的优点

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

6.状态模式与策略模式的比较

1.对状态进行建模时,状态迁移是一个核心内容;然而,在选择策略时,迁移与此毫无关系。另外,策略模式允许一个客户选择或提供一种策略,而这种思想在状态模式中完全没有;
2.策略模式用于随不同外部环境采取不同行为的场合;
3.在状态模式中,状态的迁移是由对象的内部条件决定,外界只关心起接口,不必关心其状态对象的创建与转化;而策略模式里,采取何种策略由外部条件决定

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

散一世繁华,颠半世琉璃

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值