0
点赞
收藏
分享

微信扫一扫

大聪明教你学Java设计模式 | 第十八篇:状态模式

q松_松q 2022-04-19 阅读 76

前言

大聪明在写代码的过程中发现设计模式的影子是无处不在,设计模式也是软件开发人员在软件开发过程中面临的一般问题的解决方案。大聪明本着“独乐乐不如众乐乐”的宗旨与大家分享一下设计模式的学习心得。

状态模式

🍓🍓什么是状态模式🍓🍓

在讲状态模式之前,我们先来看一下它的定义👇

我们在开发软件的时候,经常会遇到应用程序中的部分对象可能会根据不同的情况做出不同的行为的情况,我们把这种对象称为有状态的对象,而把那些可以动态变化的属性称为状态。当有状态的对象与外部事件产生互动时,其内部状态就会发生改变,从而使其行为也发生改变。就像我们在见到喜欢的人的时候,我们会开心,脸上会露出幸福的笑容;有人惹我们生气的时候,我们就会很愤怒,脸上自然也是冷冰冰的,这就是状态的改变。

那么我们在处理这种情况时,传统的解决方案就是将这些所有可能发生的情况全都考虑到,然后使用 if-else 或 switch-case 语句来做状态判断,再进行不同情况的处理。但是显然这种做法存在着明显的弊端,它对复杂的状态进行判断时,势必会导致条件判断语句会过于臃肿,可读性也会降低,且不具备扩展性,维护难度也大。那么当我们需要增加新的状态时就要添加新的 if-else 语句或 switch-case 语句,这违背了“开闭原则”,不利于程序的扩展。这时候就需要使用状态模式来帮助我们解决这类问题了,它可以把相关“判断逻辑”提取出来,用各个不同的类进行表示,系统处于哪种情况,直接使用相应的状态类对象进行处理,这样能把原来复杂的逻辑判断简单化,消除了 if-else、switch-case 等冗余语句,代码更有层次性,并且具备良好的扩展力。

🍓🍓状态模式的实现🍓🍓

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

  • 环境类(Context)角色:也称为上下文,它定义了客户端需要的接口,内部维护一个当前状态,并负责具体状态的切换。
  • 抽象状态(State)角色:定义一个接口,用以封装环境对象中的特定状态所对应的行为,可以有一个或多个行为。
  • 具体状态(Concrete State)角色:实现抽象状态所对应的行为,并且在需要的情况下进行状态切换。

那么我们就用代码来实现一下这三个角色:

🍎🍎创建环境类🍎🍎

/**
 * 环境类
 * @description: Context
 * @author: 庄霸.liziye
 * @create: 2022-04-19 20:50
 **/
public class Context {

    /**
     * 状态
     */
    private State state;

    public Context(){
        state = null;
    }

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

    public State getState(){
        return state;
    }
}

🍎🍎创建抽象状态接口🍎🍎

/**
 * 抽象状态接口
 * @description: State
 * @author: 庄霸.liziye
 * @create: 2022-04-19 20:49
 **/
public interface State {
    public void doAction(Context context);
}

🍎🍎创建抽象状态接口实现类(具体状态) 🍎🍎

/**
 * 具体状态类
 * @description: StartState
 * @author: 庄霸.liziye
 * @create: 2022-04-19 20:51
 **/
class StartState implements State {

    @Override
    public void changeState(Context context) {
        System.out.println("现在是启动状态~");
        context.setState(this);
    }

    @Override
    public String toString(){
        return "启动状态";
    }
}

class StopState implements State {

    @Override
    public void changeState(Context context) {
        System.out.println("现在是停止状态~");
        context.setState(this);
    }

    @Override
    public String toString(){
        return "停止状态";
    }
}

🍎🍎模拟状态切换 🍎🍎

/**
 * @description: Test
 * @author: 庄霸.liziye
 * @create: 2022-04-11 11:31
 **/
public class Test {

    public static void main(String[] args) {
        Context context = new Context();

        StartState startState = new StartState();
        startState.changeState(context);

        System.out.println(context.getState().toString());

        StopState stopState = new StopState();
        stopState.changeState(context);

        System.out.println(context.getState().toString());
    }
}

🍎🍎代码运行结果 🍎🍎

在这里插入图片描述

🍓🍓状态模式和策略模式的联系与区别🍓🍓

状态模式是策略模式的孪生兄弟,确切的说状态模式包含策略模式。虽然二者长得像,但二者的意图却完全不一样,策略模式是让用户指定更换的策略算法,而状态模式是状态在满足一定条件下的自动更换,用户并不能指定状态(最多只能设置初始状态)。下面我们一起看看二者的具体区别:

  1. 状态模式重点在各状态之间的切换,从而做不同的事情;而策略模式更侧重于根据具体情况选择策略,并不涉及切换。
  2. 状态模式不同状态下做的事情不同,而策略模式做的都是同一件事。
  3. 状态模式封装了对象的状态,而策略模式封装算法或策略。因为状态是跟对象密切相关的,它不能被重用;而策略模式通过从 Context 中分离出策略或算法,我们可以重用这些策略。

🍓🍓状态模式的优、缺点🍓🍓

最后我们总结一下状态模式的优点与缺点👇

🍌🍌优点🍌🍌

🍌🍌缺点🍌🍌

小结

本人经验有限,有些地方可能讲的没有特别到位,如果您在阅读的时候想到了什么问题,欢迎在评论区留言,我们后续再一一探讨🙇‍

如果文章中有错误,欢迎大家留言指正;若您有更好、更独到的理解,欢迎您在留言区留下您的宝贵想法。

举报

相关推荐

0 条评论