状态模式详解附有代码案例分析(包含状态模式与其他相关设计模式的对比)

状态模式

一、状态模式的概念以及角色

(一)、状态模式的概念

​ 状态模式也称为状态机模式,是允许对象在内部状态发送改变时改变它的行为,对象看起来好像修改了它的类,属于行为型模式。

​ 状态模式中类的行为是由状态决定的,不同的状态下有不同的行为。其意图是让一个对象在其内部改变的时候,其行为也随之改变。状态模式核心是状态与行为绑定,不同的状态对应不同的行为。

(二)、状态模式的角色

​ 1、环境类角色(Context):定义客户端需要的接口,内部维护一个当前状态实例,并负责具体状态的切换。

​ 2、抽象状态角色(State):定义该状态下的行为,可以有一个或多个行为。

​ 3、具体状态角色(ConcreteState):具体实现该状态对应的行为,并且在需要的情况下进行状态切换。

二、状态模式的应用场景

​ 1、行为随状态改变而改变的场景。

​ 2、一个操作中含有庞大的多分支结构,并且这些分支取决于对象的状态。

三、状态模式的代码示例

UserState:

public abstract class UserState {

    protected AppContext context;

    public void setContext(AppContext context){
        this.context = context;
    }

    public abstract void favorite();

    public abstract void comment(String comment);
}

LoginState:

public class LoginState extends UserState {
    
    @Override
    public void favorite() {
        System.out.println("收藏成功");
    }

    @Override
    public void comment(String comment) {
        System.out.println(comment);
    }
}

UnLoginState:

public class UnLoginState extends UserState {

    @Override
    public void favorite() {
        this.switchToLogin();
        this.context.getCurrentState().favorite();
    }


    @Override
    public void comment(String comment) {
        this.switchToLogin();
        this.context.getCurrentState().comment(comment);
    }

    private void switchToLogin() {
        System.out.println("跳转到登录页面");
        this.context.setCurrentState(AppContext.STATE_LOGIN);
    }
}

AppContext:

public class AppContext {

    public static final UserState STATE_LOGIN = new LoginState();
    public static final UserState STATE_UNLOGIN = new UnLoginState();
    private UserState currentState = STATE_UNLOGIN;

    {
        STATE_LOGIN.setContext(this);
        STATE_UNLOGIN.setContext(this);
    }

    public AppContext(UserState currentState) {
        this.currentState = currentState;
        this.currentState.setContext(this);
    }

    public UserState getCurrentState() {
        return currentState;
    }

    public void setCurrentState(UserState currentState) {
        this.currentState = currentState;
    }

    public void favorite() {
        this.currentState.favorite();
    }

    public void comment(String comment) {
        this.currentState.comment(comment);
    }

    public AppContext() {
    }
}

测试类:

public class Main {

    public static void main(String[] args) {
        // 默认不传值为未登录
        AppContext appContext = new AppContext();
        appContext.favorite();
        appContext.comment("评论成功");
    }
}

类图:
在这里插入图片描述

四、状态模式相关的设计模式

(一)、状态模式与责任链模式

​ 状态模式和责任链模式都能消除if分支过多的问题。但在某一些情况下,状态模式的状态可以理解为责任,那么这种情况下,两个模式都可以使用。

​ 从定义上看,状态模式强调的是一个对象内在状态的改变,而责任链模式强调的是外部节点对象间的改变。

​ 从其代码实现上看,他们之间最大的区别就是状态模式各个状态对象知道自己下一个要进入的状态对象。而责任链模式并不清楚下一个节点处理对象,因为链式组装由客户端负责。

(二)、状态模式与策略模式

​ 状态模式和策略模式的UML类图架构几乎一样,但是他们的应用场景是不一样的。策略模式多种算法行为择其一都能满足,彼此之间是独立的,用户可自行更换策略算法。而状态模式各个状态间是存在相互广西的,彼此之间在一定条件下存在自动切换状态效果,且用户无法指定状态,只能设置初始状态。

五、状态模式的优缺点

(一)、优点

​ 1、结构清晰:将状态独立为类,消除了冗余的if…else语句,使得代码更加简洁,提高系统可维护性。

​ 2、将状态转换显示化:通常的对象内部都是使用数值类型来定义状态,状态的切换是通过赋值进行表现,不够直观。而使用状态类,在切换状态时,是以不同的类进行表示,转换目的更加明确。

​ 3、状态类职责明确且具备扩展性。

(二)、缺点

​ 1、类膨胀:如果一个事物具备很多状态,则会造成状态类太多。

​ 2、状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱。

​ 3、状态模式对开闭原则的支持不太好,对于可以切换状态的状态模式,增加新的状态类需要修改那些负责状态转换的源代码,否则无法切换到新增状态,而且修改某个状态类的行为也需要修改对应类得源代码。

六、设计模式的相关博客文章链接

1、七大设计原则的简单解释(包含合成复用原则),简单理解、快速入门,具备案例代码

链接: 七大设计原则的简单解释(包含合成复用原则),简单理解、快速入门,具备案例代码.

2、工厂模式详解附有代码案例分析(简单工厂,工厂方法,抽象工厂)

链接: 工厂模式详解附有代码案例分析(简单工厂,工厂方法,抽象工厂).

3、单例模式详解及代码案例与应用场景(饿汉式单例模式、懒汉式单例模式、注册式单例模式)

链接: 单例模式详解及代码案例与应用场景(饿汉式单例模式、懒汉式单例模式、注册式单例模式).

4、原型模式详解附有代码案例分析(浅克隆和深克隆的相关解析)

链接: 原型模式详解附有代码案例分析(浅克隆和深克隆的相关解析).

5、建造者模式详解附有代码案例分析(包含建造者模式与工厂模式的区别分析)

链接: 建造者模式详解附有代码案例分析(包含建造者模式与工厂模式的区别分析).

6、门面模式详解附有代码案例分析

链接: 门面模式详解附有代码案例分析.

7、装饰者模式详解附有代码案例分析

链接: 装饰者模式详解附有代码案例分析.

8、享元模式详解附有代码案例分析(包含享元模式的源码应用分析——String中的享元模式应用、Integer中的享元模式应用)

链接: 享元模式详解附有代码案例分析(包含享元模式的源码应用分析——String中的享元模式应用、Integer中的享元模式应用).

9、组合模式详解附有代码案例分析(包含透明组合模式、安全组合模式的代码示例)

链接: 组合模式详解附有代码案例分析(包含透明组合模式、安全组合模式的代码示例).

10、桥接模式详解附有代码案例分析

链接: 桥接模式详解附有代码案例分析.

11、适配器模式详解附有代码案例分析(包含类适配器、对象适配器以及接口适配器的代码示例)

链接: 适配器模式详解附有代码案例分析(包含类适配器、对象适配器以及接口适配器的代码示例).

12、委派模式详解附有代码案例分析(包含委派模式在JDK中的源码示例解析)

链接: 委派模式详解附有代码案例分析(包含委派模式在JDK中的源码示例解析).

13、模板方法模式详解附有代码案例分析(包含模板方法模式重构JDBC操作业务代码示例)

链接: 模板方法模式详解附有代码案例分析(包含模板方法模式重构JDBC操作业务代码示例).

14、策略模式详解附有代码案例分析(包含策略模式在源码中的应用以及代码示例)

链接: 策略模式详解附有代码案例分析(包含策略模式在源码中的应用以及代码示例).

15、责任链模式详解附有代码案例分析(包含责任链模式与建造者模式的结合代码案例)

链接: 责任链模式详解附有代码案例分析(包含责任链模式与建造者模式的结合代码案例).

16、迭代器模式详解附有代码案例分析(包含迭代器模式的源码应用分析)

链接: 迭代器模式详解附有代码案例分析(包含迭代器模式的源码应用分析).

17、命令模式详解附有代码案例分析(包含命令模式的源码应用分析)

链接: 命令模式详解附有代码案例分析(包含命令模式的源码应用分析).

18、状态模式详解附有代码案例分析(包含状态模式与其他相关设计模式的对比)

链接: 状态模式详解附有代码案例分析(包含状态模式与其他相关设计模式的对比).

19、备忘录模式详解附有代码案例分析

链接: 备忘录模式详解附有代码案例分析.

20、中介者模式详解附有代码案例分析

链接: 中介者模式详解附有代码案例分析.

21、解释器模式详解附有代码案例分析

链接: 解释器模式详解附有代码案例分析.

22、观察者模式详解附有代码案例分析(包含观察者模式使用JDK方式实现)

链接: 观察者模式详解附有代码案例分析(包含观察者模式使用JDK方式实现).

23、访问者模式详解附有代码案例分析

链接: 访问者模式详解附有代码案例分析.

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值