Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save sachaarbonel/d5255bdb57515a4d814372e8d1ea8dbc to your computer and use it in GitHub Desktop.
Save sachaarbonel/d5255bdb57515a4d814372e8d1ea8dbc to your computer and use it in GitHub Desktop.
Visitor Pattern in Golang
package main
//Thanks to http://ecs.victoria.ac.nz/foswiki/pub/Main/TechnicalReportSeries/ECSTR11-01.pdf
import (
"fmt"
)
//We will have multiple car parts
type CarPart interface {
Accept(CarPartVisitor)
}
type Wheel struct {
Name string
}
func (this *Wheel) Accept(visitor CarPartVisitor) {
visitor.visitWheel(this)
}
type Engine struct {}
func (this *Engine) Accept(visitor CarPartVisitor) {
visitor.visitEngine(this)
}
type Car struct {
parts []CarPart
}
func NewCar() *Car {
this := new(Car)
this.parts = []CarPart{
&Wheel{"front left"},
&Wheel{"front right"},
&Wheel{"rear right"},
&Wheel{"rear left"},
&Engine{}}
return this
}
func (this *Car) Accept(visitor CarPartVisitor) {
for _, part := range this.parts {
part.Accept(visitor)
}
}
//Interface of the visitor
type CarPartVisitor interface {
visitWheel(wheel *Wheel)
visitEngine(engine *Engine)
}
//Concrete Implementation of the visitor
type GetMessageVisitor struct{
Messages []string
}
func (this *GetMessageVisitor) visitWheel(wheel *Wheel) {
this.Messages = append(this.Messages, fmt.Sprintf("Visiting the %v wheel\n", wheel.Name))
}
func (this *GetMessageVisitor) visitEngine(engine *Engine) {
this.Messages = append(this.Messages, fmt.Sprintf("Visiting engine\n"))
}
//Usage of the visitor
func main() {
car := NewCar()
visitor := new(GetMessageVisitor)
car.Accept(visitor)
fmt.Println(visitor.Messages)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment