24. 状态模式

原文地址: 状态模式 更多内容请关注:智想天开

1. 状态模式简介

状态模式(State Pattern)是一种行为型设计模式,它允许一个对象在其内部状态改变时改变其行为,使得该对象看起来似乎修改了其类。状态模式通过将状态的行为封装到独立的状态类中,实现了对象行为的动态切换,避免了大量的条件判断语句(如if-elseswitch-case)。

关键点:

  • 状态封装:将不同的状态及其对应的行为封装到独立的状态类中。

  • 动态切换:对象可以在运行时根据内部状态切换其行为。

  • 单一职责:每个状态类负责其特定状态下的行为,实现了职责的明确划分。

  • 避免条件判断:通过多态性替代条件判断,提升代码的可维护性和可扩展性。


2. 状态模式的意图

状态模式的主要目的是:

  • 封装状态相关的行为:将对象的不同状态及其对应的行为封装到独立的状态类中。

  • 实现对象行为的动态切换:允许对象在运行时根据内部状态切换其行为,而无需修改对象的类。

  • 简化复杂的条件判断:通过状态类的多态性,避免在对象方法中使用大量的条件判断语句。

  • 提高系统的可维护性和可扩展性:通过清晰的职责划分和开放/封闭原则,便于系统的维护和功能的扩展。

  • 支持状态的可复用性:独立的状态类可以在多个上下文中复用,提升代码的复用性。


3. 状态模式的结构

3.1. 结构组成

状态模式主要由以下四个角色组成:

  1. Context(上下文):维护一个具体状态对象的引用,定义了客户端所感兴趣的接口。上下文的行为依赖于当前的状态对象,并通过委托给当前状态对象来执行相应的行为。

  2. State(状态接口):定义了一个接口,用于封装与上下文的一个特定状态相关的行为。

  3. ConcreteState(具体状态):实现了State接口,定义了与上下文的一个特定状态相关的行为。

  4. Client(客户端):创建一个上下文对象并初始化其状态。

角色关系:

  • Context 持有一个 State 对象的引用。

  • State 接口由多个 ConcreteState 类实现。

  • ConcreteState 实现了与特定状态相关的行为,并可以根据需要切换上下文的状态。

  • Client 与 Context 交互,触发状态的变化。

3.2. UML类图

以下是状态模式的简化UML类图:

+-----------------+          +----------------------------+          +------------------+
|     Client      |          |    Context                 |          |     State        |
+-----------------+          +----------------------------+          +------------------+
|                 |<>------->| - state: State             |          | + handle(): void |
|                 |          +----------------------------+          +------------------+
|                 |          | + setState(s: State): void |                  ^
|                 |          | + request(): void          |                  |
|                 |          +----------------------------+                  |
+-----------------+                                                          ||+-----------------+|ConcreteStateA   |+-----------------+| + handle(): void|+-----------------+|+-----------------+|ConcreteStateB   |+-----------------+| + handle(): void|+-----------------+

说明:

  • Client 通过调用 Context 的 request() 方法来触发状态相关的行为。

  • Context 委托给当前的 State 对象来执行行为。

  • ConcreteStateA 和 ConcreteStateB 实现了 State 接口,并在 handle() 方法中定义了具体的行为和可能的状态切换。


4. 状态模式的实现

状态模式的实现需要确保上下文对象能够根据内部状态动态切换行为。以下示例将展示如何在Java和Python中实现状态模式。以一个简单的电灯开关为例,实现电灯的开关状态管理。

4.1. Java 实现示例

示例说明

我们将实现一个简单的电灯开关系统,电灯有开(On)和关(Off)两种状态。通过状态模式,实现电灯状态的切换和相应的行为执行。

代码实现
// State接口
public interface State {void handle();
}// ConcreteStateA类(开状态)
public class OnState implements State {@Overridepublic void handle() {System.out.println("电灯已经开启。");}
}// ConcreteStateB类(关状态)
public class OffState implements State {@Overridepublic void handle() {System.out.println("电灯已经关闭。");}
}// Context类
public class LightSwitch {private State currentState;public LightSwitch() {// 初始状态为关this.currentState = new OffState();}public void setState(State state) {this.currentState = state;}public void press() {currentState.handle();// 状态切换if (currentState instanceof OffState) {setState(new OnState());} else {setState(new OffState());}}
}// 客户端代码
public class StatePatternDemo {public static void main(String[] args) {LightSwitch lightSwitch = new LightSwitch();lightSwitch.press(); // 打开电灯lightSwitch.press(); // 关闭电灯lightSwitch.press(); // 打开电灯lightSwitch.press(); // 关闭电灯}
}
输出
电灯已经关闭。
电灯已经开启。
电灯已经关闭。
电灯已经开启。
代码说明
  • State接口:定义了电灯状态的行为接口 handle()

  • OnState类(ConcreteStateA):实现了 handle() 方法,表示电灯开启时的行为。

  • OffState类(ConcreteStateB):实现了 handle() 方法,表示电灯关闭时的行为。

  • LightSwitch类(Context):维护当前的状态对象,初始状态为关闭。press() 方法触发当前状态的行为,并根据当前状态切换到另一状态。

  • StatePatternDemo类:客户端,创建了电灯开关对象,并模拟了多次按下开关的过程。

4.2. Python 实现示例

示例说明

同样,实现一个简单的电灯开关系统,电灯有开(On)和关(Off)两种状态。通过状态模式,实现电灯状态的切换和相应的行为执行。

代码实现
from abc import ABC, abstractmethod# State抽象类
class State(ABC):@abstractmethoddef handle(self):pass# ConcreteStateA类(开状态)
class OnState(State):def handle(self):print("电灯已经开启。")# ConcreteStateB类(关状态)
class OffState(State):def handle(self):print("电灯已经关闭。")# Context类
class LightSwitch:def __init__(self):# 初始状态为关self._state = OffState()def set_state(self, state: State):self._state = statedef press(self):self._state.handle()# 状态切换if isinstance(self._state, OffState):self.set_state(OnState())else:self.set_state(OffState())# 客户端代码
def state_pattern_demo():light_switch = LightSwitch()light_switch.press()  # 打开电灯light_switch.press()  # 关闭电灯light_switch.press()  # 打开电灯light_switch.press()  # 关闭电灯if __name__ == "__main__":state_pattern_demo()
输出
电灯已经关闭。
电灯已经开启。
电灯已经关闭。
电灯已经开启。
代码说明
  • State抽象类:定义了电灯状态的行为接口 handle()

  • OnState类(ConcreteStateA):实现了 handle() 方法,表示电灯开启时的行为。

  • OffState类(ConcreteStateB):实现了 handle() 方法,表示电灯关闭时的行为。

  • LightSwitch类(Context):维护当前的状态对象,初始状态为关闭。press() 方法触发当前状态的行为,并根据当前状态切换到另一状态。

  • state_pattern_demo函数:客户端,创建了电灯开关对象,并模拟了多次按下开关的过程。


5. 状态模式的适用场景

状态模式适用于以下场景:

  1. 对象的行为取决于其状态:对象的行为随着其内部状态的变化而变化,且对象必须根据当前状态改变其行为。

  2. 需要避免大量的条件判断:当对象的行为需要依赖于大量的条件判断时,状态模式可以通过状态类的多态性简化代码。

  3. 状态转换频繁且复杂:当对象的状态转换频繁且复杂,状态模式可以通过封装状态类来管理状态转换。

  4. 需要动态切换对象的状态:在运行时根据对象的内部状态动态地切换行为。

  5. 需要明确划分状态相关的行为:通过状态类的独立,实现职责的明确划分,增强代码的可维护性。

示例应用场景:

  • 电灯开关系统:根据电灯的当前状态(开/关)执行不同的操作。

  • 游戏角色状态管理:角色的行为(如移动、攻击)根据当前状态(如正常、受伤、死亡)而变化。

  • TCP协议状态管理:TCP连接的状态(如建立、关闭、监听)影响其行为。

  • 订单处理系统:订单的状态(如新建、处理中、已完成、已取消)决定其处理流程。

  • 文档编辑器:根据文档的状态(如只读、编辑、保存)限制或允许不同的操作。


6. 状态模式的优缺点

6.1. 优点

  1. 封装性强:将与特定状态相关的行为封装到独立的状态类中,确保职责的明确划分。

  2. 简化复杂的条件判断:通过多态性替代大量的if-elseswitch-case语句,提升代码的可读性和可维护性。

  3. 增强系统的灵活性和可扩展性:可以方便地增加新的状态类,而无需修改现有的上下文类或其他状态类。

  4. 支持状态的可复用性:独立的状态类可以在不同的上下文中复用,提升代码的复用性。

  5. 遵循开闭原则:系统对扩展开放,对修改关闭,通过添加新的状态类实现功能的扩展。

6.2. 缺点

  1. 增加类的数量:每个状态需要一个独立的状态类,可能导致系统中类的数量增加,增加了设计的复杂性。

  2. 系统设计复杂:状态模式的实现涉及多个类和接口,需要较好的设计才能确保系统的清晰和可维护性。

  3. 上下文类可能较复杂:上下文类需要维护当前的状态对象,并在必要时切换状态,可能增加上下文类的复杂性。

  4. 状态之间可能存在耦合:某些实现可能导致不同状态类之间存在耦合关系,影响系统的灵活性。

  5. 调试难度增加:多个状态类的存在可能使得系统的调试变得更加复杂,特别是在状态转换频繁的情况下。


7. 状态模式的常见误区与解决方案

7.1. 误区1:过度使用状态模式

问题描述: 开发者可能倾向于将所有可能的状态和相关行为都通过状态模式实现,导致系统中充斥着大量的状态类,增加了系统的复杂性和维护成本。

解决方案:

  • 评估必要性:仅在确实需要对象行为依赖于状态且状态变化复杂的场景下使用状态模式。

  • 合理设计状态类:确保每个状态类的职责单一,避免状态类之间的重复和冗余。

  • 结合其他模式:在适当的情况下,结合使用其他设计模式(如策略模式),实现更灵活的设计。

7.2. 误区2:忽视状态类的内聚性

问题描述: 状态类可能因为职责不明确或功能混乱,导致内聚性差,影响系统的可维护性和可扩展性。

解决方案:

  • 明确职责:每个状态类只负责与其特定状态相关的行为,遵循单一职责原则。

  • 高内聚低耦合:确保状态类内部的实现高度内聚,与其他状态类之间保持低耦合。

  • 使用接口和抽象类:通过接口或抽象类定义状态行为,确保状态类的行为一致性。

7.3. 误区3:状态类之间存在不必要的依赖

问题描述: 状态类之间可能由于设计不当,存在不必要的依赖关系,导致系统的耦合度增加。

解决方案:

  • 设计松散耦合的状态类:状态类应独立实现,不依赖于其他状态类。

  • 通过上下文类管理状态切换:由上下文类负责管理状态对象的切换,避免状态类直接引用或依赖其他状态类。

  • 遵循开闭原则:通过接口或抽象类定义状态行为,使得状态类之间不直接依赖具体实现。


8. 状态模式的实际应用实例

8.1. 游戏角色状态管理

示例说明

在游戏中,角色可能有多种状态,如正常、受伤、死亡等。通过状态模式,实现角色状态的管理和相应行为的切换。

Java实现示例
// State接口
public interface CharacterState {void handle();
}// ConcreteStateA类(正常状态)
public class NormalState implements CharacterState {@Overridepublic void handle() {System.out.println("角色处于正常状态,可以自由移动和攻击。");}
}// ConcreteStateB类(受伤状态)
public class InjuredState implements CharacterState {@Overridepublic void handle() {System.out.println("角色受伤,移动速度减慢,攻击力降低。");}
}// ConcreteStateC类(死亡状态)
public class DeadState implements CharacterState {@Overridepublic void handle() {System.out.println("角色已死亡,无法进行任何操作。");}
}// Context类
public class GameCharacter {private CharacterState currentState;public GameCharacter() {// 初始状态为正常this.currentState = new NormalState();}public void setState(CharacterState state) {this.currentState = state;}public void performAction() {currentState.handle();}
}// 客户端代码
public class StatePatternGameDemo {public static void main(String[] args) {GameCharacter character = new GameCharacter();character.performAction(); // 正常状态character.setState(new InjuredState());character.performAction(); // 受伤状态character.setState(new DeadState());character.performAction(); // 死亡状态}
}
输出
角色处于正常状态,可以自由移动和攻击。
角色受伤,移动速度减慢,攻击力降低。
角色已死亡,无法进行任何操作。
代码说明
  • CharacterState接口:定义了角色状态的行为接口 handle()

  • NormalState类(ConcreteStateA):实现了 handle() 方法,表示角色处于正常状态时的行为。

  • InjuredState类(ConcreteStateB):实现了 handle() 方法,表示角色受伤状态时的行为。

  • DeadState类(ConcreteStateC):实现了 handle() 方法,表示角色死亡状态时的行为。

  • GameCharacter类(Context):维护当前的状态对象,初始状态为正常。performAction() 方法触发当前状态的行为。

  • StatePatternGameDemo类:客户端,创建了游戏角色对象,并演示了状态的切换和行为的执行。

8.2. TCP连接状态管理

示例说明

在TCP协议中,连接具有多种状态,如建立、监听、关闭等。通过状态模式,实现TCP连接状态的管理和相应行为的切换。

Python实现示例
from abc import ABC, abstractmethod# State抽象类
class TCPState(ABC):@abstractmethoddef open(self, tcp):pass@abstractmethoddef close(self, tcp):pass@abstractmethoddef acknowledge(self, tcp):pass# ConcreteStateA类(Closed状态)
class ClosedState(TCPState):def open(self, tcp):print("TCP连接正在打开...")tcp.set_state(OpenState())def close(self, tcp):print("TCP连接已经关闭。")def acknowledge(self, tcp):print("TCP连接尚未打开,无法确认。")# ConcreteStateB类(Open状态)
class OpenState(TCPState):def open(self, tcp):print("TCP连接已经打开。")def close(self, tcp):print("TCP连接正在关闭...")tcp.set_state(ClosedState())def acknowledge(self, tcp):print("TCP连接确认成功。")# Context类
class TCPConnection:def __init__(self):self._state = ClosedState()def set_state(self, state: TCPState):self._state = statedef open(self):self._state.open(self)def close(self):self._state.close(self)def acknowledge(self):self._state.acknowledge(self)# 客户端代码
def state_pattern_tcp_demo():tcp = TCPConnection()tcp.acknowledge()  # 尝试确认,尚未打开tcp.open()         # 打开连接tcp.acknowledge()  # 确认连接tcp.close()        # 关闭连接tcp.acknowledge()  # 尝试确认,已关闭if __name__ == "__main__":state_pattern_tcp_demo()
输出
TCP连接尚未打开,无法确认。
TCP连接正在打开...
TCP连接确认成功。
TCP连接正在关闭...
TCP连接尚未打开,无法确认。
代码说明
  • TCPState抽象类:定义了TCP连接状态的行为接口 open()close(), 和 acknowledge()

  • ClosedState类(ConcreteStateA):实现了 open()close(), 和 acknowledge() 方法,表示TCP连接关闭状态时的行为。

  • OpenState类(ConcreteStateB):实现了 open()close(), 和 acknowledge() 方法,表示TCP连接打开状态时的行为。

  • TCPConnection类(Context):维护当前的状态对象,初始状态为关闭。open()close(), 和 acknowledge() 方法委托给当前状态对象。

  • state_pattern_tcp_demo函数:客户端,创建了TCP连接对象,并演示了状态的切换和行为的执行。

8.3. 订单处理系统的状态管理

示例说明

在电子商务系统中,订单可能经历多个状态,如新建、处理中、已发货、已完成、已取消等。通过状态模式,实现订单状态的管理和相应行为的切换。

Java实现示例
// State接口
public interface OrderState {void handle(OrderContext context);
}// ConcreteStateA类(新建状态)
public class NewState implements OrderState {@Overridepublic void handle(OrderContext context) {System.out.println("订单已创建,等待处理。");context.setState(new ProcessingState());}
}// ConcreteStateB类(处理中状态)
public class ProcessingState implements OrderState {@Overridepublic void handle(OrderContext context) {System.out.println("订单正在处理中。");context.setState(new ShippedState());}
}// ConcreteStateC类(已发货状态)
public class ShippedState implements OrderState {@Overridepublic void handle(OrderContext context) {System.out.println("订单已发货。");context.setState(new CompletedState());}
}// ConcreteStateD类(已完成状态)
public class CompletedState implements OrderState {@Overridepublic void handle(OrderContext context) {System.out.println("订单已完成。");}
}// ConcreteStateE类(已取消状态)
public class CancelledState implements OrderState {@Overridepublic void handle(OrderContext context) {System.out.println("订单已取消。");}
}// Context类
public class OrderContext {private OrderState currentState;public OrderContext() {this.currentState = new NewState();}public void setState(OrderState state) {this.currentState = state;}public void process() {currentState.handle(this);}// 取消订单的方法public void cancel() {if (!(currentState instanceof CompletedState) && !(currentState instanceof CancelledState)) {setState(new CancelledState());System.out.println("订单被取消。");} else {System.out.println("无法取消订单,订单已完成或已取消。");}}
}// 客户端代码
public class StatePatternOrderDemo {public static void main(String[] args) {OrderContext order = new OrderContext();order.process(); // 新建 -> 处理中order.process(); // 处理中 -> 已发货order.cancel();  // 已发货 -> 已取消order.process(); // 已取消,无法继续处理}
}
输出
订单已创建,等待处理。
订单正在处理中。
订单已发货。
无法取消订单,订单已完成或已取消。
代码说明
  • OrderState接口:定义了订单状态的行为接口 handle()

  • NewState类(ConcreteStateA):实现了 handle() 方法,表示订单新建状态时的行为,并切换到处理中状态。

  • ProcessingState类(ConcreteStateB):实现了 handle() 方法,表示订单处理中状态时的行为,并切换到已发货状态。

  • ShippedState类(ConcreteStateC):实现了 handle() 方法,表示订单已发货状态时的行为,并切换到已完成状态。

  • CompletedState类(ConcreteStateD):实现了 handle() 方法,表示订单已完成状态时的行为。

  • CancelledState类(ConcreteStateE):实现了 handle() 方法,表示订单已取消状态时的行为。

  • OrderContext类(Context):维护当前的状态对象,初始状态为新建。process() 方法委托给当前状态对象执行行为。cancel() 方法用于取消订单,根据当前状态决定是否可以取消。

  • StatePatternOrderDemo类:客户端,创建了订单对象,并演示了订单状态的切换和取消操作。


9. 状态模式与其他模式的比较

9.1. 状态模式 vs. 策略模式

  • 状态模式用于管理对象的内部状态,对象的行为随状态的变化而变化。

  • 策略模式用于定义一系列算法,并使得它们可以相互替换,算法的变化不会影响使用它的客户端。

关键区别:

  • 目的不同:状态模式关注对象行为的动态变化,策略模式关注算法的封装与替换。

  • 结构不同:状态模式的上下文对象可能会修改其状态对象,而策略模式的上下文对象通常不会改变所使用的策略。

  • 应用场景不同:状态模式适用于对象的行为需要根据状态变化而变化的场景,策略模式适用于需要在运行时动态选择算法的场景。

9.2. 状态模式 vs. 观察者模式

  • 状态模式用于管理对象的内部状态,对象的行为随状态的变化而变化。

  • 观察者模式用于建立一对多的通信机制,当一个对象的状态变化时,所有依赖于它的对象都会得到通知并自动更新。

关键区别:

  • 目的不同:状态模式关注对象行为的动态变化,观察者模式关注对象状态的同步与通知。

  • 结构不同:状态模式通过状态对象管理行为,观察者模式通过被观察者通知观察者。

  • 应用场景不同:状态模式适用于对象行为依赖于状态的场景,观察者模式适用于需要对象间状态同步的场景。

9.3. 状态模式 vs. 责任链模式

  • 状态模式用于管理对象的内部状态,对象的行为随状态的变化而变化。

  • 责任链模式用于将请求沿着一条链传递,直到有一个对象处理请求。

关键区别:

  • 目的不同:状态模式关注对象行为的动态变化,责任链模式关注请求的处理流程。

  • 结构不同:状态模式通过状态对象管理行为,责任链模式通过链式结构传递请求。

  • 应用场景不同:状态模式适用于对象行为依赖于状态的场景,责任链模式适用于需要动态决定请求处理者的场景。

9.4. 状态模式 vs. 备忘录模式

  • 状态模式用于管理对象的内部状态,对象的行为随状态的变化而变化。

  • 备忘录模式用于保存和恢复对象的内部状态,支持撤销和重做功能。

关键区别:

  • 目的不同:状态模式关注对象行为的动态变化,备忘录模式关注对象状态的保存与恢复。

  • 结构不同:状态模式通过状态对象管理行为,备忘录模式通过备忘录对象保存和恢复状态。

  • 应用场景不同:状态模式适用于对象行为依赖于状态的场景,备忘录模式适用于需要保存和恢复对象状态的场景。


10. 状态模式的扩展与变体

状态模式在实际应用中可以根据需求进行一些扩展和变体,以适应不同的场景和需求。

10.1. 状态机实现

在复杂的系统中,对象可能有多个状态以及复杂的状态转换逻辑。此时,可以结合状态模式和状态机的概念,实现更为复杂和灵活的状态管理。

实现方式:

  • 定义状态图:通过图形化或代码形式定义状态之间的转换关系。

  • 使用状态机框架:借助现有的状态机框架,如Java的Spring State Machine,实现状态管理。

  • 集中管理状态转换:在上下文类中集中管理状态之间的转换,避免状态类之间的直接依赖。

10.2. 状态持久化

在某些应用中,需要持久化对象的状态,以便在系统重启或故障恢复后能够恢复对象的状态。

实现方式:

  • 序列化状态对象:将状态对象序列化存储到文件、数据库或其他存储介质中。

  • 状态对象的重建:在系统启动时,反序列化状态对象,并恢复上下文对象的状态。

  • 结合备忘录模式:通过备忘录模式保存和恢复状态,实现状态的持久化管理。

10.3. 状态模式与组合模式结合

在某些情况下,状态对象本身可能具有复杂的结构,可以结合组合模式,实现状态对象的层次化管理。

实现方式:

  • 定义组合状态:将多个状态对象组合成一个复杂的状态结构。

  • 递归处理:在上下文对象的状态切换过程中,递归处理组合状态的行为。

  • 增强灵活性:通过组合模式,提升状态对象的灵活性和可扩展性。


11. 总结

状态模式(State Pattern) 通过封装对象的内部状态,实现了对象行为的动态切换,增强了系统的灵活性和可维护性。该模式适用于对象行为依赖于其内部状态且状态变化复杂的场景,通过将状态的行为封装到独立的状态类中,避免了大量的条件判断语句,提升了代码的可读性和可扩展性。

关键学习点回顾:

  1. 理解状态模式的核心概念:通过状态对象管理对象的行为,实现行为的动态切换。

  2. 掌握状态模式的结构:包括Context、State接口、ConcreteState类之间的关系。

  3. 识别适用的应用场景:对象行为依赖于状态、需要避免复杂条件判断、状态变化频繁且复杂等。

  4. 认识状态模式的优缺点:封装性强、简化条件判断、增强灵活性和可扩展性;但可能导致类数量增加、系统设计复杂、上下文类复杂等。

  5. 理解常见误区及解决方案:避免过度使用、确保状态类的内聚性、避免状态类之间的不必要依赖等。

  6. 实际应用中的状态模式实例:电灯开关系统、游戏角色状态管理、TCP连接状态管理、订单处理系统等。

  7. 状态模式的扩展与变体:状态机实现、状态持久化、状态模式与组合模式结合等。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/73991.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Qt】Qt + Modbus 服务端学习笔记

《Qt Modbus 服务端学习笔记》 1.因为项目的需要&#xff0c;要写一个modbus通信&#xff0c;csdn上感觉有些回答&#xff0c;代码是人工智能生成的&#xff0c;有些细节不对。我这个经过实测&#xff0c;是可以直接用的。 首先要包含Qt 的相关模块 Qt Modbus 模块主要包含以…

CherryStudio + 火山引擎DeepSeek R1 告别服务器繁忙

CherryStudio 火山引擎DeepSeek R1 告别服务器繁忙 一、下载CherryStudio并安装 CherryStudio是功能强大的多模型桌面客户端&#xff0c;支持Windows、macOS和Linux系统。集成了多种主流的大语言模型&#xff08;如OpenAI、DeepSeek、Gemini等&#xff09;以及本地模型运行功…

医院人事科室病区管理系统基于Spring Boot-SSM

目录 摘要 一、研究背景与意义 二、国内外研究现状 三. 系统目标 四、研究目的与内容 五、研究方法与技术路线 5.1 系统技术架构 六. 系统功能 6.1 人事管理 6.2 科室病区管理 6.3 科研管理 七. 系统安全性 八. 系统运行与维护 摘要 随着医疗行业的快速发展和医院…

Unity TextMeshPro中显示建筑特殊符号

示例&#xff1a;显示效果如图 实现步骤 1、下载 SJQY 字体库 2、导入字体&#xff1a;将 SJQY 字体文件&#xff08;如 .ttf 或 .otf 文件&#xff09;导入到 Unity 项目的 Assets 文件夹中。 3、创建 TMP 字体资产 方法一 方法二 选择刚导入的字体文件&#xff0c;在…

工具层handle_excel

该工具类利用openpyxl的load_workbook加载Excel&#xff0c;通过iter_rows按行迭代数据&#xff0c;将表头和用例数据用zipdict组合成字典&#xff0c;通过list.append将字典(单条测试用例)追加到列表中&#xff0c;从而封装Excel数据解析工具。 模块/类方法/属性使用场景描述o…

九、JavaScript作用域、预解析

一、JavaScript作用域 1.JavaScript作用域 ①代码名字&#xff08;变量&#xff09;在某个范围内起作用和效果 目的是为了提高程序的可靠性更重要的是减少命名冲突 ②js的作用域&#xff08;es6&#xff09;之前&#xff1a;全局作用域 局部作用域 ③全局作用域&#xff1a;整…

Rust语言学习

Rust语言学习 通用编程概念所有权所有权引用和借用slice struct(结构体)定义并实例化一个结构体使用结构体方法语法 枚举 enums定义枚举match控制流运算符if let 简单控制流 使用包、Crate和模块管理不断增长的项目&#xff08;模块系统&#xff09;包和crate定义模块来控制作用…

Windows Docker 报错: has no HTTPS proxy,换源

pull python 3.7报错&#xff1a; 尝试拉取Docker 测试库hello world也失败 尝试使用临时镜像源&#xff0c;可以成功拉取&#xff1a; sudo docker pull docker.m.daocloud.io/hello-world说明确实是网络问题&#xff0c;需要配置镜像源&#xff0c;为了方便&#xff0c;在d…

Git远程拉取和推送配置

Git进行远程代码拉取和推送时候提示配置user.name 和 user.email 背景&#xff1a;换新电脑后使用Git进行代码拉取和推送过程中&#xff0c;提示“Make sure you configure your “user.name” and “user.email” in git.”。这个配置针对git的正常使用仅需要配置一次&#xf…

详解string类+迭代器

迭代器 概念&#xff1a;在 C 中&#xff0c;迭代器是访问容器&#xff08;如数组、列表、向量、字符串等&#xff09;元素的一种方式。迭代器提供了一种统一的接口&#xff0c;使得你可以使用相同的代码来遍历不同类型的容器。迭代器本质上是一个指针或者指针的封装&#xff0…

小红书不绑定手机号会显示ip吗

小红书作为一个生活方式分享平台&#xff0c;拥有庞大的用户群体。在小红书上&#xff0c;用户可以分享自己的生活点滴、购物心得、美食体验等&#xff0c;与其他用户进行互动交流。最近&#xff0c;不少用户对于小红书是否会在不绑定手机号的情况下显示IP属地产生了疑问&#…

Web-Machine-N7靶机实战攻略

1.安装并开启靶机 下载VirtualBox&#xff1a;https://www.virtualbox.org 导入虚拟机 设置为桥接模式 2.获取靶机IP Kali设为桥接模式 3.访问靶机 4.获取敏感目录文件和端口 gobuster dir -u http://172.16.2.68 -w /usr/share/wordlists/dirbuster/directory-list-2.3-me…

wsl配置指南

wsl配置步骤 1.安装2.列出当前的发行版3.导出要迁移的发行版&#xff0c;并指定导出的路径及文件名4.注销掉已经导出的发行版5.重新导入到新的路径&#xff0c;可以指定新的名称6.修改默认用户7.更换source8.配置gpu环境 1.安装 在microsoft store中搜索ubuntu&#xff0c;选择…

Linux|fork命令及其使用的写时拷贝技术

fork复制进程 fork通过以下步骤来复制进程&#xff1a; 分配新的进程控制块&#xff1a;内核为新进程分配一个新的进程控制块&#xff08;PCB&#xff09;&#xff0c;用于存储进程的相关信息&#xff0c;如进程 ID、状态、寄存器值、内存指针等。复制进程地址空间&#xff1…

Android Compose 框架基础按钮模块深度剖析(四)

Android Compose 框架基础按钮模块深度剖析 一、引言 在现代 Android 应用开发中&#xff0c;Android Compose 框架以其声明式编程范式和简洁高效的开发体验&#xff0c;逐渐成为开发者构建用户界面的首选。而注解在 Android Compose 框架中扮演着至关重要的角色&#xff0c;…

HarmonyOS开发,A持有B,B引用A的场景会不会导致内存泄漏,看这里!

问题 :A持有B,B引用A的场景会不会导致内存泄漏? 答案 :方舟虚拟机的内存管理和GC采用的是根可达算法,根可达算法可以解决循环引用问题,不会导致A引用B,B引用A的内存泄漏。 根可达算法原理 根可达算法以一系列被称为 “根对象”(如栈中的局部变量、静态变量等)作为起…

【数据库备份】docker中数据库备份脚本——MySql备份脚本

docker中数据库备份脚本——MySql备份脚本 #!/bin/bash# MySQL数据库信息 DB_USER"root" DB_PASSWORD"你的密码"# 备份保存主目录 BACKUP_ROOT"/data/data_backup/mysql"# 最多保留的备份日期文件夹数 MAX_DATE_FOLDERS15# 数组包含要备份的数据…

TCP、UDP协议的应用、ServerSocket和Socket、DatagramSocket和DatagramPacket

DAY13.1 Java核心基础 TCP协议 TCP 协议是面向连接的运算层协议&#xff0c;比较复杂&#xff0c;应用程序在使用TCP协议之前必须建立连接&#xff0c;才能传输数据&#xff0c;数据传输完毕之后需要释放连接 就好比现实生活中的打电话&#xff0c;首先确保电话打通了才能进…

Web爬虫利器FireCrawl:全方位助力AI训练与高效数据抓取

Web爬虫利器FireCrawl&#xff1a;全方位助力AI训练与高效数据抓取 一、FireCrawl 项目简介二、主要功能三、FireCrawl应用场景1. 大语言模型训练2. 检索增强生成&#xff08;RAG&#xff09;&#xff1a;3. 数据驱动的开发项目4. SEO 与内容优化5. 在线服务与工具集成 四、安装…

excel文件有两列,循环读取文件两列赋值到字典列表。字典的有两个key,分别为question和answer。将最终结果输出到json文件

import pandas as pd import json# 1. 读取 Excel 文件&#xff08;假设列名为 question 和 answer&#xff09; try:df pd.read_excel("input.xlsx", usecols["question", "answer"]) # 明确指定列 except Exception as e:print(f"读取文…