Go Visitor Pattern
This is kind of cool … Go Playground Example
package main
//Thanks to http://ecs.victoria.ac.nz/foswiki/pub/Main/TechnicalReportSeries/ECSTR11-01.pdf
/*
Ref:
https://gist.github.com/francoishill/f0624e7760aacdc96b42
*/
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{
HP string
}
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{HP: "500 cc"}}
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 %v engine\n", engine.HP))
}
//Usage of the visitor
func main() {
car := NewCar()
visitor := new(GetMessageVisitor)
car.Accept(visitor)
fmt.Println(visitor.Messages)
}
Facade Pattern
package main
import "fmt"
type Circle struct {
}
func (c *Circle) draw() {
fmt.Printf("Drawing Circle\n")
}
type Square struct {
}
func (s *Square) Draw() {
fmt.Printf("Drawing Square\n")
}
type ShapeMaker struct {
circle *Circle
square *Square
}
func (s *ShapeMaker) DrawCircle() {
s.circle.draw()
}
func (s *ShapeMaker) DrawSquare() {
s.square.Draw()
}
func main() {
s := ShapeMaker{}
s.DrawCircle()
s.DrawSquare()
}
Completion Handler Go
package main
import (
"fmt"
)
func AddNumberToString(i int, completion func(s string) string) string {
return fmt.Sprintf("%d %s\n", i, completion("one"))
}
func main() {
m := AddNumberToString(3, func(s string) string {
s = fmt.Sprintf(" %s %s %s\n", s, s, "test")
return s
})
fmt.Println(m)
}