模式定义
允许一个对象在其内部状态改变时改变它的行为,从而使对象看起来似乎修改了其行为
类图
要点总结
- State模式将所有与一个特定状态相关的行为都放入一个State的子类对象中,在对象状态切换时,切换相应的对象,但同时维持State的接口,这样实现了具体操作与状态转换之间的解耦
- 为不同的状态引入不同的对象使得状态转换变得更加明确,而且可以保证不会出现状态不一致的情况,因为转化是原子性的–即要么彻底转化过来,要么不转换
- 如果State对象没有实例变量,那么各个上下文可以共享一个State对象,从而节省对象开销
Go语言代码实现
状态模式(State Pattern)是一种行为型设计模式,它允许对象在内部状态改变时改变其行为。状态模式通过将状态封装成独立的类,并将对象的行为委托给当前状态对象来实现。
状态模式的核心思想是将对象的状态抽象成一个个独立的类,每个状态类都实现了相同的接口,以便对象可以在不同状态下执行相应的行为。通过改变对象的状态对象,可以改变对象的行为,而无需改变对象本身。
以下是一个简单的例子来说明状态模式的应用:
package main
import "fmt"
// State 接口定义了状态的行为
type State interface {
Handle()
}
// Context 上下文对象
type Context struct {
state State
}
func NewContext() *Context {
return &Context{
state: nil,
}
}
func (c *Context) SetState(state State) {
c.state = state
}
func (c *Context) Request() {
if c.state != nil {
c.state.Handle()
} else {
fmt.Println("Invalid state")
}
}
// ConcreteStateA 具体状态A
type ConcreteStateA struct{}
func (s *ConcreteStateA) Handle() {
fmt.Println("Handling request in State A")
}
// ConcreteStateB 具体状态B
type ConcreteStateB struct{}
func (s *ConcreteStateB) Handle() {
fmt.Println("Handling request in State B")
}
func main() {
context := NewContext()
stateA := &ConcreteStateA{}
context.SetState(stateA)
context.Request()
stateB := &ConcreteStateB{}
context.SetState(stateB)
context.Request()
}
在上述示例中,我们定义了一个状态接口State,它声明了状态的行为方法Handle。然后,我们创建了一个上下文对象Context,它持有一个状态对象。
具体的状态类ConcreteStateA和ConcreteStateB实现了状态接口,并根据具体的状态执行相应的行为。
在main函数中,我们创建了上下文对象,并通过设置不同的状态对象来改变上下文对象的状态。然后,我们通过调用上下文对象的请求方法来触发相应的行为,上下文对象会根据当前的状态对象执行相应的行为。
通过状态模式,我们可以将对象的行为与其状态分离,使得对象在内部状态改变时能够改变其行为,同时也使得状态的变化更加灵活和可扩展。状态模式对于具有复杂状态转换和需要根据状态执行不同行为的对象非常有用。
状态模式和策略模式的异同点
状态模式(State Pattern)和策略模式(Strategy Pattern)是两种行为型设计模式,它们有一些相似之处,但也存在一些明显的差异。
异同点如下:
相同点:
两者都涉及对象行为的封装和委托。
状态模式和策略模式都能够使得对象的行为具有灵活性和可扩展性。
两者都通过将行为抽象成不同的类来实现不同行为之间的切换。
不同点:
目的不同:状态模式的目的是根据对象的内部状态改变对象的行为,以实现状态的切换;策略模式的目的是根据不同的策略选择合适的行为,以实现不同的算法或策略的切换。
状态的关注点不同:状态模式关注的是对象内部的状态变化,每个状态都对应一种行为;策略模式关注的是将不同的算法或策略封装成不同的类,使得这些算法或策略可以互相替换。
结构不同:状态模式通常涉及一个上下文对象和多个具体状态类,上下文对象持有一个当前状态对象;策略模式通常涉及一个上下文对象和多个具体策略类,上下文对象持有一个具体策略对象。
使用场景不同:状态模式适用于对象有多个状态,且状态之间有相互转换的场景;策略模式适用于需要根据不同的算法或策略选择不同行为的场景。
总之,状态模式和策略模式在目的、关注点、结构和使用场景上存在明显的差异。状态模式用于根据对象的内部状态改变行为,而策略模式用于选择不同的算法或策略来实现不同的行为。