博主介绍: ✌博主从事应用安全和大数据领域,有8年研发经验,5年面试官经验,Java技术专家✌
Java知识图谱点击链接:体系化学习Java(Java面试专题)
💕💕 感兴趣的同学可以收藏关注下 ,不然下次找不到哟💕💕
文章目录
- 1、什么是状态模式
- 2、状态模式的优缺点
- 3、状态模式的应用场景
- 4、状态模式的结构
- 5、状态模式的原理
- 6、状态模式的代码案例
1、什么是状态模式
状态模式是一种行为型设计模式,它允许对象在内部状态改变时改变其行为。在状态模式中,对象的行为取决于其内部状态,而不是取决于外部输入。通过将状态封装成独立的类,并将状态之间的转换逻辑封装在上下文类中,状态模式使得状态的变化更加灵活和可扩展。
在状态模式中,通常会有一个上下文类(Context)和多个具体状态类(Concrete State)。上下文类包含一个当前状态的引用,它会根据当前状态委托相应的行为给具体状态类。当上下文类的状态发生改变时,它会调用具体状态类的方法来实现不同的行为。
2、状态模式的优缺点
状态模式的优点包括:
-
将状态的转换逻辑封装在具体状态类中,使得状态变化更加清晰和可维护。
-
通过引入新的具体状态类,可以方便地扩展系统的功能。
-
遵循开闭原则,对于上下文类而言,可以在不修改其代码的情况下增加新的状态类。
-
状态模式将状态的判断逻辑分散到具体状态类中,避免了大量的条件语句,提高了代码的可读性和可维护性。
状态模式的缺点包括:
-
引入了多个状态类,增加了系统的复杂性。
-
如果状态转换过于复杂,可能会导致状态类之间的相互调用和依赖关系复杂化。
-
如果状态转换的逻辑不够清晰,可能会导致状态切换的错误或不完整。
需要根据具体的应用场景来评估是否使用状态模式。在状态变化较为简单且有限的情况下,可能不需要引入状态模式,而在状态变化复杂且需要灵活扩展的情况下,状态模式可以提供一种清晰和可维护的设计方案。
3、状态模式的应用场景
状态模式适用于以下场景:
-
对象的行为随着其内部状态的改变而改变,并且需要在运行时动态地改变对象的行为。
-
对象具有多个状态,并且在不同状态下有不同的行为。
-
有大量的条件语句用于根据对象的状态进行不同的操作,导致代码复杂且难以维护。
-
需要在运行时根据对象的状态来决定不同的行为,而不是通过条件语句的方式。
-
需要在不修改现有代码的情况下增加新的状态和行为。
-
需要将状态转换的逻辑封装在具体状态类中,使得代码更加可读和可维护。
一些常见的应用场景包括:
-
订单状态管理:订单可能有不同的状态,如待支付、待发货、已发货等,每个状态对应着不同的行为和操作。
-
游戏角色状态:游戏中的角色可能有不同的状态,如正常状态、受伤状态、死亡状态等,每个状态对应着不同的行为和表现。
-
线程状态管理:线程可能有不同的状态,如新建状态、运行状态、阻塞状态等,每个状态对应着不同的行为和操作。
-
电梯控制系统:电梯可能有不同的状态,如停止状态、运行状态、故障状态等,每个状态对应着不同的行为和操作。
总之,状态模式适用于对象的行为随着其内部状态的改变而改变的情况,可以帮助简化代码、提高可维护性和扩展性。
4、状态模式的结构
状态模式的结构包括以下几个角色:
-
环境(Context):环境类是拥有状态的对象,它维护一个对抽象状态类的引用,并在运行时切换状态。环境类将客户端的请求委派给当前状态对象来处理。
-
抽象状态(State):抽象状态类定义了一个接口,用于封装与环境类的特定状态相关的行为。它可以是一个抽象类或接口,并且包含了环境类的引用,以便在需要时切换到其他状态。
-
具体状态(Concrete State):具体状态类是抽象状态的子类,实现了抽象状态定义的接口。每个具体状态类对应着环境的一个具体状态,负责处理该状态下的行为和操作。
在状态模式中,环境类通过委派给当前状态对象来处理请求,而不是使用条件语句来判断状态并执行相应的操作。这样可以将状态的转换逻辑封装在具体状态类中,使得环境类的代码更加简洁、可读和可维护。
状态模式通过将对象的行为和状态分离,使得对象的行为可以根据其内部状态的改变而改变,同时也方便了新状态的添加和扩展。这种模式可以提高代码的可维护性、可扩展性和可读性。
5、状态模式的原理
状态模式的原理是基于对象的状态来改变对象的行为。它将对象的行为封装成不同的状态类,并将状态的转换逻辑放在环境类中。当对象的状态发生改变时,环境类会委托当前状态对象来处理相应的行为。
状态模式的核心思想是将复杂的条件判断语句转换为对状态对象的委派,从而简化了代码的结构和逻辑。它通过将每个状态封装成独立的类,使得每个状态都可以单独进行扩展和修改,而不会影响其他状态的实现。
在状态模式中,环境类拥有一个对抽象状态类的引用,并在运行时根据需要切换到不同的具体状态对象。环境类将客户端的请求委托给当前状态对象来处理,而具体的行为实现则由具体状态类来完成。
6、状态模式的代码案例
以下是一个简单的状态模式的代码示例,以展示状态模式的实现方式:
package com.pany.camp.design.principle.state;
/**
*
* @description: 状态接口
* @copyright: @Copyright (c) 2022
* @company: Aiocloud
* @author: pany
* @version: 1.0.0
* @createTime: 2023-06-28 14:54
*/
public interface State {
void handle();
}
package com.pany.camp.design.principle.state;
/**
*
* @description: 具体状态类A
* @copyright: @Copyright (c) 2022
* @company: Aiocloud
* @author: pany
* @version: 1.0.0
* @createTime: 2023-06-28 14:55
*/
class ConcreteStateA implements State {
@Override
public void handle() {
System.out.println("当前状态是A,执行A状态的处理逻辑");
}
}
package com.pany.camp.design.principle.state;
/**
*
* @description: 具体状态类B
* @copyright: @Copyright (c) 2022
* @company: Aiocloud
* @author: pany
* @version: 1.0.0
* @createTime: 2023-06-28 14:56
*/
class ConcreteStateB implements State {
@Override
public void handle() {
System.out.println("当前状态是B,执行B状态的处理逻辑");
}
}
package com.pany.camp.design.principle.state;
/**
*
* @description: 环境类
* @copyright: @Copyright (c) 2022
* @company: Aiocloud
* @author: pany
* @version: 1.0.0
* @createTime: 2023-06-28 14:56
*/
class Context {
private State state;
public void setState(State state) {
this.state = state;
}
public void request() {
state.handle();
}
}
package com.pany.camp.design.principle.state;
/**
*
* @description: 客户端类
* @copyright: @Copyright (c) 2022
* @company: Aiocloud
* @author: pany
* @version: 1.0.0
* @createTime: 2023-06-28 14:56
*/
public class Client {
public static void main(String[] args) {
Context context = new Context();
State stateA = new ConcreteStateA();
State stateB = new ConcreteStateB();
// 设置初始状态为A
context.setState(stateA);
context.request(); // 输出:当前状态是A,执行A状态的处理逻辑
// 切换状态为B
context.setState(stateB);
context.request(); // 输出:当前状态是B,执行B状态的处理逻辑
}
}
状态接口 State 定义了 handle() 方法,具体的状态类 ConcreteStateA 和 ConcreteStateB 实现了该接口,并分别实现了不同的处理逻辑。环境类 Context 持有一个对当前状态的引用,并在 request() 方法中委托当前状态对象来处理请求。
在测试代码中,首先创建了一个环境类 Context 和两个具体状态类 ConcreteStateA 和 ConcreteStateB 。通过 setState() 方法设置初始状态为A,并调用 request() 方法来执行当前状态的处理逻辑。然后,通过再次调用 setState() 方法切换状态为B,并再次调用 request() 方法来执行B状态的处理逻辑。
输出结果如下:
当前状态是A,执行A状态的处理逻辑
当前状态是B,执行B状态的处理逻辑
Process finished with exit code 0
💕💕 本文由激流原创,首发于CSDN博客,博客主页 https://blog.csdn.net/qq_37967783?spm=1010.2135.3001.5421
💕💕喜欢的话记得点赞收藏啊