专栏介绍
专栏地址
专栏介绍
主要对目前市面上常见的23种设计模式进行逐一分析和总结,希望有兴趣的小伙伴们可以看一下,会持续更新的。希望各位可以监督我,我们一起学习进步,加油,各位。
状态模式
状态模式是一种行为型设计模式,它允许一个对象在内部状态发生变化时改变其行为。状态模式将对象的行为封装在不同的状态类中,通过改变对象的状态来改变其行为。
关键角色
上下文(Context)
上下文是一个包含状态的对象,它定义了客户端与状态对象的交互接口。上下文中维护了一个指向当前状态的引用,并且在运行时可以切换到不同的状态。上下文将客户端请求委派给当前状态对象处理。
抽象状态(State)
抽象状态是一个接口或抽象类,它定义了状态对象的通用行为。具体状态类需要实现这个接口或继承这个抽象类,并且根据具体的状态来实现相应的行为。
具体状态(Concrete State)
具体状态是实现抽象状态的具体类。每个具体状态类都代表了上下文在特定状态下的行为。具体状态类负责处理上下文的请求,并在需要时切换到其他状态。
核心思想
将状态的判断和状态的行为分离,使得状态的变化不影响行为的变化。通过将状态的行为封装在具体状态类中,可以方便地添加新的状态或修改现有状态的行为,同时也避免了状态判断的复杂性。
Java程序实现
首先,我们定义一个抽象状态类 State,其中包含一个处理请求的方法 handleRequest():
public abstract class State { public abstract void handleRequest(); }
然后,我们创建两个具体状态类 ConcreteStateA 和 ConcreteStateB,它们分别实现了抽象状态类 State:
public class ConcreteStateA extends State { @Override public void handleRequest() { System.out.println("处理请求,当前状态为A"); } } public class ConcreteStateB extends State { @Override public void handleRequest() { System.out.println("处理请求,当前状态为B"); } }
接下来,我们创建一个上下文类 Context,其中包含一个指向当前状态的引用,并提供了一个方法 setState() 用于切换状态和一个方法 request() 用于处理请求:
public class Context { private State currentState; public Context() { // 初始化为初始状态 currentState = new ConcreteStateA(); } public void setState(State state) { currentState = state; } public void request() { currentState.handleRequest(); } }
最后,我们可以在客户端代码中使用上下文类来测试状态模式的效果:
public class Client { public static void main(String[] args) { Context context = new Context(); // 处理请求,当前状态为A context.request(); // 切换状态为B context.setState(new ConcreteStateB()); // 处理请求,当前状态为B context.request(); } }
输出结果
处理请求,当前状态为A 处理请求,当前状态为B
分析
在上述示例中,我们通过状态模式实现了一个简单的上下文对象 Context,它可以根据不同的状态来处理请求。通过切换状态,上下文对象可以改变其行为。这样,我们可以方便地添加新的状态类或修改现有状态的行为,而不需要修改客户端代码。
优缺点分析
优点
1
通过将状态的行为封装在具体状态类中,可以使得状态的变化对客户端透明,客户端只需要与上下文进行交互,不需要关心具体的状态。
2
增加新的状态类相对容易,符合开闭原则,不需要修改现有的代码。
3
将状态的行为集中到具体状态类中,使得代码更加清晰,易于维护和扩展。
缺点
1
当状态的行为比较少或简单时,使用状态模式可能会导致类的数量增加,增加了代码的复杂性。
2
如果状态之间存在相互转换的复杂逻辑,可能需要引入其他模式来处理状态之间的转换。
总结
状态模式是一种通过将状态的行为封装在具体状态类中,使得状态的变化不影响行为的设计模式。它可以使代码更加清晰、易于维护和扩展,适用于状态变化较多且状态之间的行为差异较大的场景。