上一篇《备忘录模式》 下一篇《访问者模式》
状态模式,它是一种对象行为型模式,它允许一个对象在其内部状态改变时改变它的行为。这种模式可以让一个对象的行为随着状态的改变而改变,增强了代码的可维护性和灵活性。
在状态模式中,通常有一个状态的接口,以及一些具体状态类。这些具体状态类实现了状态的接口,并定义了在该状态下对象的行为。上下文类则包含一个状态对象,并定义了如何改变状态的方法。在上下文类中,根据当前状态和请求,可以调用当前状态的 Handle 方法来处理请求,并更新状态。
状态模式的使用场景:
1、一个对象存在多个状态,状态可以相互转换。
2、不同状态下,行为不同。
3、代码中包含大量与对象状态有关的 if/else 或 switch case 语句,且这些条件执行与否依赖于该对象的状态。
状态模式的创建步骤:
1、创建一个接口,表示状态的抽象。
2、创建实现接口的实体类,表示具体状态。
3、创建一个上下文类,包含一个状态对象,并定义如何改变状态的方法。
4、在上下文类中,根据当前状态和请求,调用当前状态的 Handle 方法来处理请求,并更新状态。
以上是状态模式的基本创建步骤,您可以根据实际应用场景进行调整和扩展。
状态模式的优点,主要包括:
1、封装了状态的转换规则,将状态的转换代码封装在环境类或者具体状态类中,集中管理状态转换代码,而不是分散在一个个业务方法中。
2、将所有与某个状态有关的行为放到一个类中,只需要注入一个不同的状态对象即可使环境对象拥有不同的行为。
3、允许状态转换逻辑与状态对象合成一体,而不是提供一个巨大的条件语句块,从而避免将业务方法和状态转换代码交织在一起。
4、可以让多个环境对象共享一个状态对象,从而减少系统中对象的个数。
状态模式的缺点,主要包括:
1、类膨胀:如果一个事物具备很多状态,则会造成状态类太多,导致系统复杂度增加。
2、状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱。
3、状态模式对开闭原则的支持不太好,对于可以切换状态的状态模式,增加新的状态类需要修改那些负责状态转换的源代码,否则无法切换到新增状态。
4、如果状态数量比较多,状态类的数量会增加,业务场景系统变得很复杂。
以下是一个示例,展示了如何在C#中实现状态模式:
//首先定义一个状态的接口:
public interface State
{
void Handle(Context context);
}
//然后定义一些具体的状态:
public class StateA : State
{
public void Handle(Context context)
{
Console.WriteLine("State A handled. Switching to State B");
context.State = new StateB();
}
}
public class StateB : State
{
public void Handle(Context context)
{
Console.WriteLine("State B handled. Switching to State A");
context.State = new StateA();
}
}
//然后定义一个上下文(Context)类,它包含一个状态对象,并定义如何改变状态的方法:
public class Context
{
private State _state;
public Context(State state)
{
this._state = state;
}
public State State { get { return _state; } }
public void Request() => _state.Handle(this);
}
//最后在主函数中使用:
public static void Main(string[] args)
{
var stateA = new StateA();
var context = new Context(stateA);
context.Request();
}
状态模式通常通过以下方式实现:
//首先定义一个状态的接口:
public interface State {
void handle(Context context);
}
//然后定义一些具体的状态:
public class StateA implements State {
@Override
public void handle(Context context) {
System.out.println("State A handled. Switching to State B");
context.setState(new StateB());
}
}
public class StateB implements State {
@Override
public void handle(Context context) {
System.out.println("State B handled. Switching to State A");
context.setState(new StateA());
}
}
//然后定义一个上下文(Context)类,它包含一个状态对象,并定义如何改变状态的方法:
public class Context {
private State state;
public Context(State state) {
this.state = state;
}
public void request() {
state.handle(this);
}
public void setState(State state) {
this.state = state;
}
}
//最后在主函数中使用:
public static void main(String[] args) {
StateA stateA = new StateA();
Context context = new Context(stateA);
context.request();
}
在JavaScript中,状态实现方式如下:
class Context {
constructor(state) {
this.state = state;
}
request() {
this.state.handle(this);
}
}
class State {
handle(context) {
console.log("Default state handled");
}
}
class StateA extends State {
handle(context) {
console.log("State A handled. Switching to State B");
context.state = new StateB();
}
}
class StateB extends State {
handle(context) {
console.log("State B handled. Switching to State A");
context.state = new StateA();
}
}
const stateA = new StateA();
const context = new Context(stateA);
context.request();
以下是在C++中实现状态模式:
#include
#include
class Context {
public:
void Request() {
m_state->Handle(this);
}
private:
State* m_state;
};
class State {
public:
virtual void Handle(Context* context) = 0;
};
class StateA : public State {
public:
void Handle(Context* context) override {
std::cout << "State A handled. Switching to State B" << std::endl;
context->m_state = new StateB();
}
};
class StateB : public State {
public:
void Handle(Context* context) override {
std::cout << "State B handled. Switching to State A" << std::endl;
context->m_state = new StateA();
}
};
int main() {
StateA* stateA = new StateA();
Context context(stateA);
context.Request();
}
以下是在python中实现状态模式:
from abc import ABC, abstractmethod
class Context(ABC):
@abstractmethod
def Request(self):
pass
class State(ABC):
@abstractmethod
def Handle(self, context):
pass
class StateA(State):
def Handle(self, context):
print("State A handled. Switching to State B")
context.State = StateB()
class StateB(State):
def Handle(self, context):
print("State B handled. Switching to State A")
context.State = StateA()
class Context(Context):
def __init__(self, state):
self.State = state
def Request(self):
self.State.Handle(self)
以下是一个示例,展示了如何在go中实现状态模式:
// State 接口定义了每个状态必须实现的方法
type State interface {
Handle(context *Context)
}
// ConcreteStateA 是 State 接口的具体实现
type ConcreteStateA struct{}
func (s *ConcreteStateA) Handle(context *Context) {
fmt.Println("State A handled. Switching to State B")
context.State = &ConcreteStateB{}
}
// ConcreteStateB 是 State 接口的具体实现
type ConcreteStateB struct{}
func (s *ConcreteStateB) Handle(context *Context) {
fmt.Println("State B handled. Switching to State A")
context.State = &ConcreteStateA{}
}
// Context 是包含状态的对象的结构体
type Context struct {
State State
}
func (c *Context) Request() {
c.State.Handle(c)
}
以下是一个示例,展示了如何在PHP中实现状态模式:
context->setState(new ConcreteStateB());
}
}
class ConcreteStateB implements State {
public function handle() {
echo "State B handled. Switching to State A\n";
$this->context->setState(new ConcreteStateA());
}
}
class Context {
private $state;
public function setState(State $state) {
$this->state = $state;
}
public function request() {
$this->state->handle();
}
}
// 使用状态模式示例代码:
$context = new Context();
$context->setState(new ConcreteStateA());
《完结》
上一篇《备忘录模式》 下一篇《访问者模式》