- 根据状态动态变化策略(interface指向的对象)
- 使用条件:
(1)对象的行为依赖于它的状态(属性)并且可以根据它的状态改变而改变它的相关行为。
(2)代码中包含大量与对象状态有关的条件语句,这些条件语句的出现,会导致代码的可维护性和灵活性变差,不能方便地增加和删除状态,使客户类与类库之间的耦合增强。

使用值标记状态
如果使用int状态位来判断状态:
///看帖
func (a *Account) View() {
if a.State == NORMAL || a.State == RESTRICTED {
fmt.Println("正常看帖")
} else if a.State == CLOSED {
fmt.Println("账号被封,无法看帖")
}
}
///评论
func (a *Account) Comment() {
if a.State == NORMAL || a.State == RESTRICTED {
fmt.Println("正常评论")
} else if a.State == CLOSED {
fmt.Println("抱歉,你的健康值小于-10,不能评论")
}
}
使用状态模式
在状态模式中将对象在每一个状态下的行为和状态转移语句封装在一个个状态类中,通过这些状态类来分散冗长的条件转移语句,让系统具有更好的灵活性和可扩展性。(有策略模式那味了)
- 状态切换的时候切换对象(自带方法切换)而不是值

package main
import "fmt"
type Account struct {
State ActionState
HealthValue int
}
type ActionState interface {
View()
Comment()
Post()
}
type CloseState struct {
}
func (c *CloseState) View() {
fmt.Println("账号被封,无法看帖")
}
func (c *CloseState) Comment() {
fmt.Println("抱歉,你的健康值小于-10,不能评论")
}
func (c *CloseState) Post() {
fmt.Println("抱歉,你的健康值小于0,不能发帖")
}
type RestrictedState struct {
}
func (r *RestrictedState) View() {
fmt.Println("正常看帖")
}
func (r *RestrictedState) Comment() {
fmt.Println("正常评论")
}
func (r *RestrictedState) Post() {
fmt.Println("抱歉,你的健康值小于0,不能发帖")
}
func (a *Account) changeState() {
if a.HealthValue <= -10 {
a.State = &CloseState{}
} else if a.HealthValue > -10 && a.HealthValue <= 0 {
a.State = &RestrictedState{}
} // else if a.HealthValue > 0 {
// a.State = &NormalState{}
// }
}
///给账户设定健康值
func (a *Account) SetHealth(value int) {
a.HealthValue = value
a.changeState()
}
func main() {
acc := new(Account)
acc.SetHealth(-20)
acc.State.View()
}
网友评论