设计模式——状态模式
2020-11-02 本文已影响0人
DevilRoshan
什么是状态模式?
当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。
实现
type State interface {
On(machine *Machine)
Off(machine *Machine)
}
type Machine struct {
current State
}
func NewMachine() *Machine {
return &Machine{current:NewOff()}
}
func (this *Machine)SetCurrent(state State) {
this.current = state
}
func (this *Machine)On(){
this.current.On(this)
}
func (this *Machine)Off(){
this.current.Off(this)
}
type On struct {
}
func NewOn() State {
return &On{}
}
func (this *On)On(machine *Machine){
fmt.Println("设备已经开启")
}
func (this *On)Off(machine *Machine){
fmt.Println("从On到Off状态,关闭")
machine.SetCurrent(NewOff())
}
type Off struct {
}
func NewOff() State {
return &Off{}
}
func (this *Off)On(machine *Machine){
fmt.Println("从Off状态开启至On状态")
machine.SetCurrent(NewOn())
}
func (this *Off)Off(machine *Machine){
fmt.Println("设备已经关闭")
}
func TestState(t *testing.T) {
machine := NewMachine()
machine.Off()
machine.On()
machine.On()
machine.On()
machine.Off()
machine.Off()
machine.On()
}
// === RUN TestState
// 设备已经关闭
// 从Off状态开启至On状态
// 设备已经开启
// 设备已经开启
// 从On到Off状态,关闭
// 设备已经关闭
// 从Off状态开启至On状态
// --- PASS: TestState (0.00s)
// PASS
优点
- 结构清晰,避免了过多的switch…case或if…else语句的使用;
- 很好的体现了开闭原则和单一职责原则,想要增加状态就增加子类,想要修改状态就修改子类即可;
- 封装性非常好,状态变化放置到了类的内部来实现,外部调用不需要知道类内部如何实现状态和行为的变换。
缺点
- 子类会太多,也即类膨胀。
使用场景
- 行为随状态改变而改变的场景;
- 条件、分支判断语句的替代者。
注意
- 在行为受状态约束的情况下可以使用状态模式,使用时对象的状态最好不要超过5个。