网站优化技术,在哪个网站做失业分解,网站建设与管理实用教程,做网站要什么技术Golang学习笔记_44——命令模式 Golang学习笔记_45——备忘录模式 Golang学习笔记_46——状态模式 文章目录 一、核心概念1. 定义2. 解决的问题3. 核心角色4. 类图 二、特点分析三、适用场景1. 编译器实现2. 财务系统3. UI组件系统 四、Go语言实现示例完整实现代码执行结果 五、…Golang学习笔记_44——命令模式 Golang学习笔记_45——备忘录模式 Golang学习笔记_46——状态模式 文章目录 一、核心概念1. 定义2. 解决的问题3. 核心角色4. 类图 二、特点分析三、适用场景1. 编译器实现2. 财务系统3. UI组件系统 四、Go语言实现示例完整实现代码执行结果 五、高级应用1. 异步访问者2. 动态派发优化 六、与其他模式对比七、实现建议八、典型应用 一、核心概念
1. 定义
访问者模式是一种行为型设计模式允许在不修改已有对象结构的前提下定义新的操作。其核心特点包括 • 操作解耦将数据操作与数据结构分离 • 双重分发通过两次方法调用实现动态绑定 • 扩展开放新增操作无需修改现有类
2. 解决的问题
• 操作污染频繁添加新操作导致类不断膨胀 • 聚合困难相关操作分散在不同类中 • 类型检查避免大量instanceof类型判断
3. 核心角色
角色作用Visitor声明访问操作的接口visit方法ConcreteVisitor实现具体访问逻辑Element定义接受访问者的接口accept方法ConcreteElement实现accept方法的具体元素ObjectStructure包含元素集合的容器
4. 类图 startuml
interface Visitor { visitElementA(e: ElementA) visitElementB(e: ElementB)
}class TaxVisitor { visitElementA() visitElementB()
}interface Element { accept(v: Visitor)
}class ElementA { accept(v: Visitor) operationA()
}class ElementB { accept(v: Visitor) operationB()
}Visitor |.. TaxVisitor
Element |.. ElementA
Element |.. ElementB
ElementA .. Visitor
ElementB .. Visitornote right of ElementA::accept调用visitor.visitElementA(this)实现双重分派机制
end note
enduml二、特点分析
优点
扩展性强新增访问者不影响现有系统职责清晰相关操作集中管理复合操作支持跨元素的复杂操作
缺点
破坏封装需暴露元素内部细节维护困难元素接口变更影响所有访问者适用局限适合稳定元素结构的系统
三、适用场景
1. 编译器实现
type ASTVisitor interface {VisitVariableDecl(n *VariableDecl)VisitFunctionCall(n *FunctionCall)
}type TypeChecker struct{}func (t *TypeChecker) VisitVariableDecl(n *VariableDecl) {fmt.Printf(校验变量 %s 的类型\n, n.Name)
}2. 财务系统
type FinancialVisitor interface {VisitInvoice(i *Invoice)VisitPayment(p *Payment)
}type TaxCalculator struct{}func (t *TaxCalculator) VisitInvoice(i *Invoice) {fmt.Printf(计算发票税款%.2f\n, i.Amount*0.1)
}3. UI组件系统
type UIVisitor interface {VisitButton(b *Button)VisitPanel(p *Panel)
}class Renderer struct{}func (r *Renderer) VisitButton(b *Button) {fmt.Printf(渲染按钮%s\n, b.Label)
}四、Go语言实现示例 完整实现代码
package visitor_demoimport fmt// Visitor 接口
type ComputerPartVisitor interface {VisitMouse(m *Mouse)VisitKeyboard(k *Keyboard)
}// Concrete Visitor
type DisplayVisitor struct{}func (d *DisplayVisitor) VisitMouse(m *Mouse) {fmt.Println(显示鼠标信息, m.GetSpec())
}func (d *DisplayVisitor) VisitKeyboard(k *Keyboard) {fmt.Println(显示键盘信息, k.GetLayout())
}// Element 接口
type ComputerPart interface {Accept(visitor ComputerPartVisitor)
}// Concrete Elements
type Mouse struct {dpi int
}func (m *Mouse) Accept(visitor ComputerPartVisitor) {visitor.VisitMouse(m)
}func (m *Mouse) GetSpec() string {return fmt.Sprintf(%d DPI, m.dpi)
}type Keyboard struct {layout string
}func (k *Keyboard) Accept(visitor ComputerPartVisitor) {visitor.VisitKeyboard(k)
}func (k *Keyboard) GetLayout() string {return k.layout
}// Object Structure
type Computer struct {parts []ComputerPart
}func (c *Computer) AddPart(p ComputerPart) {c.parts append(c.parts, p)
}func (c *Computer) Accept(visitor ComputerPartVisitor) {for _, p : range c.parts {p.Accept(visitor)}
}// 客户端使用示例
func ExampleUsage() {computer : Computer{parts: []ComputerPart{Mouse{dpi: 1600},Keyboard{layout: QWERTY},},}visitor : DisplayVisitor{}computer.Accept(visitor)
}执行结果 RUN TestExampleUsage
显示鼠标信息 1600 DPI
显示键盘信息 QWERTY
--- PASS: TestExampleUsage (0.00s)
PASS五、高级应用
1. 异步访问者
type AsyncVisitor interface {VisitForDB(n Node) -chan errorVisitForAPI(n Node) -chan error
}func BatchVisit(nodes []Node, v AsyncVisitor) []error {// 实现并发访问处理
}2. 动态派发优化
type DynamicVisitor struct {handlers map[reflect.Type]func(interface{})
}func (dv *DynamicVisitor) Register(t reflect.Type, fn func(interface{})) {dv.handlers[t] fn
}六、与其他模式对比
模式核心区别典型应用场景策略模式单算法选择 vs 多元素操作支付方式选择装饰器模式增强功能 vs 添加操作IO流处理组合模式树形结构 vs 元素遍历文件系统管理
七、实现建议
访问者接口设计
type Visitor interface {VisitTypeA(*TypeA)VisitTypeB(*TypeB)DefaultVisit(interface{})
}元素继承处理
type BaseElement struct{}func (b *BaseElement) Accept(v Visitor) {v.DefaultVisit(b)
}循环引用处理
type Element struct {visitor Visitor json:- // 避免序列化循环
}访问者状态管理
type StatefulVisitor struct {buffer strings.Builder
}八、典型应用
编译器构建语法树检查/优化数据分析异构数据集合统计游戏引擎场景实体遍历更新文档处理多格式导出系统
在Go语言中实现建议
使用接口组合代替继承通过类型断言实现泛型访问者结合通道实现并发访问使用sync.Pool优化高频访问对象