Go语言实现23种设计模式之行为型模式(上)

您所在的位置:网站首页 gof设计模式 Go语言实现23种设计模式之行为型模式(上)

Go语言实现23种设计模式之行为型模式(上)

2022-12-29 23:00| 来源: 网络整理| 查看: 265

使用Go实现23种设计模式——行为型模式(下) 访问者模式

在不改变各元素的类的前提下定义作用于这些元素的新操作

适用场景 数据结构相对稳定的对象,且需要经常在此结构上定义新操作 Go语言实现 type Number struct { Numbers []int } func (n *Number) Do(v IVisitor) { v.Do(n.Numbers) } type IVisitor interface { Do([]int) } type AddVisitor struct{} func (v *AddVisitor) Do(numbers []int) { sum := 0 for _, n := range numbers { sum += n } fmt.Printf("sum: %d\n", sum) } type TimesVisitor struct{} func (v *TimesVisitor) Do(numbers []int) { res := 1 for _, n := range numbers { res *= n } fmt.Printf("res: %d\n", res) } func main() { a := Number{Numbers: []int{1, 2, 3, 4}} a.Do(&AddVisitor{}) a.Do(&TimesVisitor{}) } 访问者模式优点 增加新的操作简单 访问者模式缺点 增加新的数据结构困难 模板方法模式

定义一个操作中的算法的骨架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤

适用场景 模板模式解决了一些方法通用,却在每个子类都重新写一遍的这些方法 Go语言实现 type Notify struct { } func (n *Notify) Send() { fmt.Println("send error") } type SMSNotify struct { Notify } func (n *SMSNotify) Send() { fmt.Println("send sms success") } type EMailNotify struct { Notify } func (n *EMailNotify) Send() { fmt.Println("send email success") } func main() { a := SMSNotify{} a.Send() b := EMailNotify{} b.Send() } 模板方法模式优点 封装不变的部分,扩展可变部分提取公共代码,便于维护行为由父类控制,子类实现 模板方法模式缺点 每一个不同的实例,都需要一个子类来实现,导致类的个数增加 策略模式

定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换

适用场景 一个类定义了多种行为,并且这些行为以多个if…else形式出现 Go语言实现 type Operation interface { Do(n1, n2 int) int } type OperationAdd struct { } func NewOperationAdd() *OperationAdd { return &OperationAdd{} } func (o *OperationAdd) Do(n1, n2 int) int { return n1 + n2 } type OperationSubtract struct { } func NewOperationSubtract() *OperationSubtract { return &OperationSubtract{} } func (o *OperationSubtract) Do(n1, n2 int) int { return n1 -n2 } type Context struct { operation Operation } func NewContext(operation Operation) *Context { return &Context{operation: operation} } func (c *Context) Do(n1, n2 int) int { return c.operation.Do(n1, n2) } func main() { a := NewContext(NewOperationAdd()) a.Do(1, 2) b := NewContext(NewOperationSubtract()) b.Do(3, 1) } 策略模式优点 避免使用多重判断语句算法可自由切换扩展性好 策略模式缺点 客户端需要理解所有策略算法的区别,以便选择合适的算法类策略类很多,增加维护难度 状态模式

允许一个对象在其内部状态改变时改变它的行为

适用场景 代码中包含大量与对象状态有关的条件语句 Go语言实现 type Account struct { Action State status string } func NewAccount(status string) *Account { a := &Account{status: status} a.initState() return a } func (a *Account) initState() { if a.status == "normal" { a.Action = &NormalState{} } else { a.Action = &BannedState{} } } type State interface { Login() } type NormalState struct{} func (s *NormalState) Login() { fmt.Println("登陆成功") } type BannedState struct{} func (s *BannedState) Login() { fmt.Println("账号封禁,禁止登陆") } func main() { a := NewAccount("normal") a.Action.Login() } 状态模式优点 封装了转换规则将所有与状态相关的行为放到一个类中,方便的增加状态允许状态转换逻辑和状态对象合成一体,而不是巨大的条件语句块 状态模式缺点 增加了系统中类和对象的个数,导致系统运行开销变大状态模式的结构与实现都比较复杂对"开闭原则"的支持不友好


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3