Golang设计模式——14状态模式

状态模式

定义

允许一个对象在其内部状态改变时改变它的行为,这个对象看起来就像改变了它的类一样。

优点

  1. 状态模式将与特定状态相关的行为局部化到一个状态中,并且将不同状态的行为分割开来,满足“单一职责原则”。
  2. 减少对象间的相互依赖。将不同的状态引入独立的对象中会使得状态转换变得更加明确,且减少对象间的相互依赖。
  3. 有利于程序的扩展。通过定义新的子类很容易地增加新的状态和转换。

缺点

  1. 状态模式的使用必然会增加系统的类与对象的个数。
  2. 状态模式的结构与实现都较为复杂,如果使用不当会导致程序结构和代码的混乱。
  3. 虽然状态模式可以很好的处理行为受状态约束的情况,但相应的对象的状态也会增加,所以在实际项目中使用的时候,要权衡利弊,考虑它对你的设计带来的后果影响是否可以接受。如果状态太多比如十几个或者几十个,还是建议不要使用了。

场景

  1. 行为随着状态的改变而改变的时候,这也是状态模式的根本出发点,例如权限设计,人员的状态不同即使执行相同的行为结果也会不同,在这种情况下需要考虑使用状态模式。
  2. 条件、分支判断语句的替代者,在程序中大量使用 switch 语句或者if-else判断语句会导致程序结构不清晰,逻辑混乱,使用状态模式可以很好地避免这一问题。

代码

在这里插入图片描述

package State

import "fmt"

type Context struct {
	state State
}

func NewContext() *Context {
	return &Context{state: &ConcreteStateA{}}
}

func (c *Context) SetState(state State) {
	c.state = state
}
func (c *Context) Handle() {
	c.state.Handler(c)
}

type State interface {
	Handler(*Context)
}

type ConcreteStateA struct {
}

func (c *ConcreteStateA) Handler(context *Context) {
	fmt.Println("当前状态是A")
	context.SetState(&ConcreteStateB{})
}

type ConcreteStateB struct {
}

func (c *ConcreteStateB) Handler(context *Context) {
	fmt.Println("当前状态是B")
	context.SetState(&ConcreteStateC{})

}

type ConcreteStateC struct {
}

func (c *ConcreteStateC) Handler(context *Context) {
	fmt.Println("当前状态是C")
	context.SetState(&ConcreteStateA{})
}

package State

import "testing"

func TestContext_Handle(t *testing.T) {
	context := NewContext()
	context.Handle()
	context.Handle()
	context.Handle()
	context.Handle()
	context.Handle()
}

其他设计模式

设计模式Git源代码
00简单工厂模式
01工厂方法模式
02抽象工厂模式
03外观模式
04建造者模式
05桥接模式
06命令模式
07迭代器模式
08模板模式
09访问者模式
10备忘录模式
11责任链模式
12中介模式
13原型模式
14状态模式
15策略模式
16享元模式
17组合模式
18解释器模式
19单例模式
20适配器模式
21代理模式
22装饰器模式
23观察者模式

posted @ 2021-09-25 15:07  cheems~  阅读(61)  评论(0编辑  收藏  举报