从零开始学习Java设计模式 | 行为型模式篇:状态模式

本文详细介绍了状态模式,通过电梯控制案例引出问题,阐述了状态模式的概念、结构和优缺点。状态模式允许对象在内部状态改变时改变其行为,避免了复杂的条件语句。文章通过代码实现展示了如何使用状态模式改进电梯案例,提高了代码的可读性和扩展性。
摘要由CSDN通过智能技术生成

在本讲,我们来学习一下行为型模式里面的第五个设计模式,即状态模式。

状态模式引入案例

在学习状态模式之前,我们先来看一个案例,通过该案例来引出状态模式。

这个案例就是通过电梯按钮来控制一个电梯的状态。一个电梯有开门状态、关门状态、停止状态、运行状态等四种状态。每一种状态改变,都有可能要根据其他状态来更新处理。例如,如果电梯门现在处于运行时状态,那么就不能进行开门操作。为什么呢?你想啊,现在电梯正处于运行状态呢,然后门开了,这是不是非常危险呀!所以,当电梯处于运行状态时是不允许执行开门操作的。而如果电梯门是停止状态,那么就可以执行开门操作了。

下面我们就来看一下对于以上案例所设计出来的类图。

在这里插入图片描述

从以上类图中可以看到,我们首先定义了一个ILift接口,而且它里面声明有四个常量,即OPENING_STATE、CLOSING_STATE、RUNNING_STATE、STOPPING_STATE,它们分别是来表示电梯的四种状态的,即开启状态、关闭状态、运行状态和停止状态。

此外,ILift接口还提供了5个抽象方法,它们分别是:

  1. setState(int state):设置电梯的状态。因为我们总得记录一下当前电梯的一个状态吧!
  2. open():电梯开门的方法
  3. close():电梯关门的方法
  4. stop():电梯停止的方法
  5. run():电梯运行的方法

注意,ILift接口就是用于提高程序扩展性的,如果后期有其他的实体也拥有电梯的四种状态,那么我们完全可以让它去实现该接口。

然后,我们再来看一下ILift接口的子实现类,即Lift。可以看到,在该类里面定义了一个state属性,这个属性就是用来记录当前电梯状态的。除此之外,该类还重写了父接口中的所有抽象方法。

至于那个客户端类,我们就不用过多地去关注它了。所以,整个看下来,系统设计起来还是比较简单的。接下来,我们就得编写代码来实现以上案例了。

首先,打开咱们的maven工程,并在com.meimeixia.pattern包下新建一个子包,即state.before,也即实现以上案例的具体代码我们是放在了该包下。

然后,创建电梯接口,这里我们就命名为了ILift。

package com.meimeixia.pattern.state.before;

/**
 * 电梯接口
 * @author liayun
 * @create 2021-09-17 10:44
 */
public interface ILift {
   

    // 定义四个电梯状态的常量
    int OPENING_STATE = 1;
    int CLOSING_STATE = 2;
    int RUNNING_STATE = 3;
    int STOPPING_STATE = 4;

    // 设置电梯状态的功能
    void setState(int state);

    // 电梯操作功能
    void open();

    void close();

    void run();

    void stop();

}

接着,创建电梯接口的子实现类,即电梯类,这里我们就命名为了Lift。

package com.meimeixia.pattern.state.before;

/**
 * 电梯类(ILift接口的子实现类)
 * @author liayun
 * @create 2021-09-17 10:51
 */
public class Lift implements ILift {
   

    // 声明一个记录当前电梯状态的成员变量
    private int state;

    @Override
    public void setState(int state) {
   
        this.state = state;
    }

    @Override
    public void open() {
   
        switch (state) {
    // 判断当前电梯的状态
            case OPENING_STATE:
                // 如果当前电梯正处于开启状态,那么我们再去开门,这就没有任何意义了,所以这儿我们什么事都不做
                break;
            case CLOSING_STATE:
                // 如果当前电梯正处于关闭状态,那么我们就能开电梯门了
                System.out.println("电梯打开了...");
                // 设置当前电梯状态为开启状态
                setState(OPENING_STATE);
                break;
            case STOPPING_STATE:
                // 如果当前电梯正处于停止状态,那么我们也是能开电梯门的
                System.out.println("电梯打开了...");
                // 设置当前电梯状态为开启状态
                setState(OPENING_STATE);
                break;
            case RUNNING_STATE:
                // 如果当前电梯正处于运行状态,那么我们肯定是不能去开门的,因为电梯运行时是不能开门的,所以这儿我们什么事都不做
                break;
        }
    }

    @Override
    public void close() {
   
        switch (this.state) {
   
            case OPENING_STATE:
                // 如果当前电梯正处于开启状态,那么我们就能关闭电梯门了
                System.out.println("电梯关门了...");
                // 设置当前电梯状态为关闭状态
                this.setState(CLOSING_STATE);
                break;
            case CLOSING_STATE:
                // 如果当前电梯正处于关闭状态,那么我们再去关门,这就没有任何意义了,所以这儿我们什么事都不做
                // do nothing
                break;
            case RUNNING_STATE:
                // 如果当前电梯正处于运行状态,很显然,此时电梯门肯定是关着的,那么我们就不能再去关门了,所以这儿我们什么事都不做
                // do nothing
                break;
            case STOPPING_STATE:
                // 如果当前电梯正处于停止状态,很显然,此时电梯门肯定也是关着的,那么我们就不能再去关门了,所以这儿我们什么事都不做
                // do nothing
                break;
        }
    }

    @Override
    public void run() {
   
        switch (this.state) {
   
          
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

李阿昀

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

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

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

打赏作者

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

抵扣说明:

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

余额充值