状态模式是一种行为型设计模式,它可以根据一个对象的内在状态来改变它的行为。该模式将对象的状态封装成不同的类,每个状态都会实现该对象的一个公共接口,并在发生状态转换时更改对象所维护的状态类。
这种模式主要由以下几个角色组成:
- 上下文(Context):它是状态模式中的主要角色,包含一些内部状态,用于管理不同状态的对象。上下文可以将状态转换委托给状态类来进行处理。
- 抽象状态(State):它是所有具体状态的基类。抽象状态定义了一个接口,每个具体状态都实现了这个接口。
- 具体状态(ConcreteState):它是状态模式中的具体类,它实现了抽象状态的接口,并定义了它自己的行为。具体状态类负责从上下文中获取状态的信息,并根据这些信息执行相应的行为。
使用状态模式可以使上下文和状态之间具有高度解耦,从而可以更容易的扩展和修改系统的状态转换行为。此外,状态模式还可以简化代码复杂度,减少代码冗余,提高系统的可维护性和可扩展性。
php实现
//上下文对象
type Context struct {
state State
}
//更改当前状态
func (c *Context) setState(state State) {
c.state = state
}
//获取当前状态
func (c *Context) getState() State {
return c.state
}
//公共接口
type State interface {
handle(context *Context)
}
//具体状态1
type ConcreteState1 struct{}
//实现公共接口
func (s *ConcreteState1) handle(context *Context) {
fmt.Println("当前状态为:状态1")
context.setState(new(ConcreteState2)) //状态1处理完成后切换到状态2
}
//具体状态2
type ConcreteState2 struct{}
//实现公共接口
func (s *ConcreteState2) handle(context *Context) {
fmt.Println("当前状态为:状态2")
context.setState(new(ConcreteState1)) //状态2处理完成后切换到状态1
}
//测试代码
func main() {
context := &Context{state: new(ConcreteState1)} //初始化状态为状态1
context.getState().handle(context) //处理当前状态
context.getState().handle(context) //处理当前状态
}
php实现代码:
//上下文对象
class Context {
private $state;
//更改当前状态
public function setState($state) {
$this->state = $state;
}
//获取当前状态
public function getState() {
return $this->state;
}
//执行状态处理
public function handle() {
$this->state->handle($this);
}
}
//公共接口
interface State {
public function handle(Context $context);
}
//具体状态1
class ConcreteState1 implements State {
public function handle(Context $context) {
echo "当前状态为:状态1\n";
$context->setState(new ConcreteState2()); //状态1处理完成后切换到状态2
}
}
//具体状态2
class ConcreteState2 implements State {
public function handle(Context $context) {
echo "当前状态为:状态2\n";
$context->setState(new ConcreteState1()); //状态2处理完成后切换到状态1
}
}
//测试代码
$context = new Context();
$context->setState(new ConcreteState1()); //初始化状态为状态1
$context->handle(); //处理当前状态
$context->handle(); //处理当前状态
我们首先定义了一个上下文对象Context,它包含一个内部状态state,以及用于设置和获取状态的方法setState和getState。然后,我们定义了一个公共状态接口State,所有具体状态都需要实现这个接口,并且在处理过程中通过上下文对象来获取和更改状态。最后,我们定义了两个具体状态ConcreteState1和ConcreteState2,它们实现了State接口的handle方法,并在处理过程中根据当前状态切换到另一个状态。
在测试代码中,我们首先创建了一个初始状态为ConcreteState1的上下文对象Context,并通过调用setState和handle方法来处理当前状态。在第一次处理完成后,我们将状态切换到了ConcreteState2,并再次处理当前状态。在第二次处理完成后,状态又回到了ConcreteState1,这样循环处理状态直到程序结束。