设计模式:状态模式(C#、JAVA、JavaScript、C++、Python、Go、PHP)

上一篇《备忘录模式》 下一篇《访问者模式》

简介:

状态模式,它是一种对象行为型模式,它允许一个对象在其内部状态改变时改变它的行为。这种模式可以让一个对象的行为随着状态的改变而改变,增强了代码的可维护性和灵活性。

在状态模式中,通常有一个状态的接口,以及一些具体状态类。这些具体状态类实现了状态的接口,并定义了在该状态下对象的行为。上下文类则包含一个状态对象,并定义了如何改变状态的方法。在上下文类中,根据当前状态和请求,可以调用当前状态的 Handle 方法来处理请求,并更新状态。

状态模式的使用场景:

1、一个对象存在多个状态,状态可以相互转换。

2、不同状态下,行为不同。

3、代码中包含大量与对象状态有关的 if/else 或 switch case 语句,且这些条件执行与否依赖于该对象的状态。

状态模式的创建步骤:

1、创建一个接口,表示状态的抽象。

2、创建实现接口的实体类,表示具体状态。

3、创建一个上下文类,包含一个状态对象,并定义如何改变状态的方法。

4、在上下文类中,根据当前状态和请求,调用当前状态的 Handle 方法来处理请求,并更新状态。

以上是状态模式的基本创建步骤,您可以根据实际应用场景进行调整和扩展。

状态模式的优点,主要包括:

1、封装了状态的转换规则,将状态的转换代码封装在环境类或者具体状态类中,集中管理状态转换代码,而不是分散在一个个业务方法中。

2、将所有与某个状态有关的行为放到一个类中,只需要注入一个不同的状态对象即可使环境对象拥有不同的行为。

3、允许状态转换逻辑与状态对象合成一体,而不是提供一个巨大的条件语句块,从而避免将业务方法和状态转换代码交织在一起。

4、可以让多个环境对象共享一个状态对象,从而减少系统中对象的个数。

状态模式的缺点,主要包括:

1、类膨胀:如果一个事物具备很多状态,则会造成状态类太多,导致系统复杂度增加。

2、状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱。

3、状态模式对开闭原则的支持不太好,对于可以切换状态的状态模式,增加新的状态类需要修改那些负责状态转换的源代码,否则无法切换到新增状态。

4、如果状态数量比较多,状态类的数量会增加,业务场景系统变得很复杂。

示例:

一、C#状态模式

以下是一个示例,展示了如何在C#中实现状态模式:

cs 复制代码
//首先定义一个状态的接口:
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(); 
}

二、java状态模式

状态模式通常通过以下方式实现:

java 复制代码
//首先定义一个状态的接口:
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状态模式

在JavaScript中,状态实现方式如下:

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++状态模式

以下是在C++中实现状态模式:

cpp 复制代码
#include <iostream>  
#include <string>  
  
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状态模式

以下是在python中实现状态模式:

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状态模式

以下是一个示例,展示了如何在go中实现状态模式:

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状态模式

以下是一个示例,展示了如何在PHP中实现状态模式:

php 复制代码
<?php  
interface State {  
    public function handle();  
}  
  
class ConcreteStateA implements State {  
    public function handle() {  
        echo "State A handled. Switching to State B\n";  
        $this->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()); 

《完结》

上一篇《备忘录模式》 下一篇《访问者模式》

相关推荐
矩阵科学10 个月前
行为型设计模式——状态模式
设计模式·状态模式·java状态模式·行为型状态模式