大家好,欢迎来到IT知识分享网。
设计模式-状态模式(State)
设计模式-状态模式(State)
设计模式文档无水印可复制
一、状态模式概述
1.1 什么是状态模式
Java中的状态模式是一种行为设计模式,它允许对象在其内部状态改变时改变其行为。这种模式主要用于实现对象之间的解耦,使得对象可以在不修改其结构的情况下改变其行为。
Java中的状态模式通常包括以下角色:
1.2 简单实现状态模式
// 状态接口 interface State {
void handle(Context context); } // 具体状态A class ConcreteStateA implements State {
@Override public void handle(Context context) {
System.out.println("当前状态为A"); context.setState(this); } } // 具体状态B class ConcreteStateB implements State {
@Override public void handle(Context context) {
System.out.println("当前状态为B"); context.setState(this); } } // 上下文类 class Context {
private State state; public Context() {
this.state = new ConcreteStateA(); // 初始状态为A } public void request() {
state.handle(this); // 根据当前状态执行相应操作 } public void setState(State state) {
this.state = state; // 切换状态 } } public class Main {
public static void main(String[] args) {
Context context = new Context(); // 创建上下文对象 context.request(); // 输出:当前状态为A,并切换到状态A context.request(); // 输出:当前状态为B,并切换到状态B } }
1.3 使用状态模式的注意事项
- 1、状态模式适用于当一个对象在它的状态发生改变时,它的行为也随着发生较大的变化。也就是说,在行为受状态约束的情况下可以使用状态模式。如果一个事件或者对象有很多种状态,状态之间会相互转换,对不同的状态要求不同行为的时候,可以考虑使用状态模式。
- 2、状态模式的关键点在于不同的状态下对于同一行为有不同的响应。这其实就是一个将 if~else 用多态来实现的一个具体示例。
- 3、状态模式的使用必然会增加系统类和对象的个数。尽管状态模式提供了一个更好的方法来组织与特定状态相关的代码,将繁琐的状态判断转换成结构清晰的状态类族,在避免代码膨胀的同时也保证了可扩展性与可维护性,但会增加系统的复杂性。
- 4、当使用状态模式时,需要避免过多的状态转换,如果对象的状态太多,可能会导致系统变得复杂难以维护。最好保证对象的状态不超过5个。
- 5、Context类应当尽可能地简单,它的职责主要是负责维护当前状态,并根据当前状态调用相应的状态处理方法。如果Context类过于复杂,可能会影响系统的可维护性和可扩展性。
二、状态模式的用途
- 1、当一个对象的状态改变时,它的行为也随着发生较大的变化。也就是说,在行为受状态约束的情况下可以使用状态模式。如果一个事件或者对象有很多种状态,状态之间会相互转换,对不同的状态要求不同行为的时候,可以考虑使用状态模式。
- 2、状态模式的关键点在于不同的状态下对于同一行为有不同的响应。这其实就是一个将 if~else 用多态来实现的一个具体示例。
- 3、状态模式提供了一个更好的方法来组织与特定状态相关的代码,将繁琐的状态判断转换成结构清晰的状态类族,在避免代码膨胀的同时也保证了可扩展性与可维护性。
- 4、当使用状态模式时,需要避免过多的状态转换,如果对象的状态太多,可能会导致系统变得复杂难以维护。最好保证对象的状态不超过5个。
三、状态模式实现方式
3.1 使用枚举类型实现状态模式
首先,定义一个表示状态的枚举类型:
public enum State {
STATE_A, STATE_B, STATE_C }
然后,创建一个类,该类包含一个表示当前状态的变量,并提供一个方法来更改状态:
public class StatePatternDemo {
private State currentState; public StatePatternDemo() {
currentState = State.STATE_A; } public void changeState(State newState) {
currentState = newState; performAction(); } private void performAction() {
switch (currentState) {
case STATE_A: System.out.println("执行状态 A 的操作"); break; case STATE_B: System.out.println("执行状态 B 的操作"); break; case STATE_C: System.out.println("执行状态 C 的操作"); break; } } }
最后,创建一个主类来测试状态模式:
public class Main {
public static void main(String[] args) {
StatePatternDemo demo = new StatePatternDemo(); demo.changeState(State.STATE_B); demo.changeState(State.STATE_C); } }
运行上述代码,将输出以下结果:
执行状态 A 的操作 执行状态 B 的操作 执行状态 C 的操作
3.2 使用内部类实现状态模式
首先,创建一个外部类 Context,它将包含一个表示当前状态的内部类 State 的实例变量。然后,为每个可能的状态创建一个内部类,这些类将实现一个共同的接口,该接口定义了所有状态都需要实现的方法。最后,在 Context 类中,提供一个方法来更改状态,并调用新状态的相应方法。
public class Context {
// 内部类 State,表示状态 private State state; public Context(State state) {
this.state = state; } // 更改状态的方法 public void setState(State state) {
this.state = state; } // 执行状态操作的方法 public void request() {
state.handle(); } } // 定义一个接口,表示状态需要实现的方法 interface State {
void handle(); } // 具体状态类 A class StateA implements State {
@Override public void handle() {
System.out.println("处理状态 A"); } } // 具体状态类 B class StateB implements State {
@Override public void handle() {
System.out.println("处理状态 B"); } } // 具体状态类 C class StateC implements State {
@Override public void handle() {
System.out.println("处理状态 C"); } } // 测试代码 public class Main {
public static void main(String[] args) {
Context context = new Context(new StateA()); context.request(); // 输出:处理状态 A context.setState(new StateB()); context.request(); // 输出:处理状态 B context.setState(new StateC()); context.request(); // 输出:处理状态 C } }
在这个示例中,我们创建了一个名为 Context 的外部类,它包含一个名为 State 的内部类实例变量。我们还为每个可能的状态创建了一个内部类(StateA、StateB 和 StateC),它们都实现了一个名为 State 的接口。在 Context 类中,我们提供了一个名为 setState 的方法来更改状态,并调用新状态的 handle 方法。
3.3 使用接口实现状态模式
首先,创建一个表示状态的接口:
public interface State {
void handle(Context context); }
然后,创建具体的状态类,实现State接口:
public class ConcreteStateA implements State {
@Override public void handle(Context context) {
System.out.println("当前状态是A"); context.setState(new ConcreteStateB()); } } public class ConcreteStateB implements State {
@Override public void handle(Context context) {
System.out.println("当前状态是B"); context.setState(new ConcreteStateA()); } }
接下来,创建一个上下文类,用于存储当前状态,并实现State接口:
public class Context {
private State state; public Context() {
state = new ConcreteStateA(); } public void setState(State state) {
this.state = state; } public void request() {
state.handle(this); } }
最后,在主函数中测试状态模式:
public class StatePatternDemo {
public static void main(String[] args) {
Context context = new Context(); context.request(); // 输出:当前状态是A context.request(); // 输出:当前状态是B context.request(); // 输出:当前状态是A } }
在这个示例中,我们定义了一个State接口,以及两个具体的状态类ConcreteStateA和ConcreteStateB。Context类负责存储当前状态,并在需要时切换状态。通过调用Context类的request方法,我们可以在不同状态之间进行切换。
3.4 使用抽象类实现状态模式
首先,创建一个表示状态的抽象类State:
public abstract class State {
public abstract void handle(Context context); }
然后,创建具体的状态类,例如StartState和StopState:
public class StartState extends State {
@Override public void handle(Context context) {
System.out.println("启动状态"); context.setState(new StopState()); } } public class StopState extends State {
@Override public void handle(Context context) {
System.out.println("停止状态"); context.setState(new StartState()); } }
接下来,创建一个表示上下文的类Context,并包含一个State类型的成员变量:
public class Context {
private State state; public Context() {
this.state = new StartState(); } public void setState(State state) {
this.state = state; } public void request() {
state.handle(this); } }
最后,在主函数中测试状态模式:
public class Main {
public static void main(String[] args) {
Context context = new Context(); context.request(); // 输出:启动状态 context.request(); // 输出:停止状态 context.request(); // 输出:启动状态 } }
在这个示例中,我们使用抽象类State定义了状态的接口,并创建了两个具体的状态类StartState和StopState。Context类负责管理当前状态,并在需要时切换状态。通过调用context.request()方法,我们可以在不同状态之间进行切换。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/117275.html