// behavorial package pattern import ( "fmt" ) // 13. Chain of Responsibility Pattern type Handler interface { SetNext(handler Handler) Handle(request string) string } type AbstractHandler struct { next Handler } func (h *AbstractHandler) SetNext(handler Handler) { h.next = handler } type ConcreteHandler1 struct { AbstractHandler } func (h *ConcreteHandler1) Handle(request string) string { if request == "one" { return "Handler1: handled" } if h.next != nil { return h.next.Handle(request) } return "" } // 14. Command Pattern type Command interface { Execute() string } type Light struct{} func (l *Light) TurnOn() string { return "Light is on" } func (l *Light) TurnOff() string { return "Light is off" } type LightOnCommand struct { light *Light } func (c *LightOnCommand) Execute() string { return c.light.TurnOn() } // 15. Interpreter Pattern type Expression interface { Interpret() bool } type TerminalExpression struct { data string } func (t *TerminalExpression) Interpret() bool { return len(t.data) > 0 } // 16. Iterator Pattern type Iterator interface { HasNext() bool Next() interface{} } type Collection struct { items []interface{} } type CollectionIterator struct { collection *Collection index int } func (i *CollectionIterator) HasNext() bool { return i.index < len(i.collection.items) } func (i *CollectionIterator) Next() interface{} { if i.HasNext() { item := i.collection.items[i.index] i.index++ return item } return nil } // 17. Mediator Pattern type Mediator interface { Notify(sender string, event string) } type ConcreteMediator struct { component1 *Component1 component2 *Component2 } type Component1 struct { mediator Mediator } type Component2 struct { mediator Mediator } func (m *ConcreteMediator) Notify(sender string, event string) { fmt.Printf("Mediator reacts on %s and triggers event: %s\n", sender, event) } // 18. Memento Pattern type Memento struct { state string } type Originator struct { state string } func (o *Originator) CreateMemento() *Memento { return &Memento{state: o.state} } func (o *Originator) RestoreMemento(m *Memento) { o.state = m.state } // 19. Observer Pattern type Observer interface { Update(string) } type Subject2 struct { observers []Observer state string } func (s *Subject2) Attach(o Observer) { s.observers = append(s.observers, o) } func (s *Subject2) Notify() { for _, observer := range s.observers { observer.Update(s.state) } } // 20. State Pattern type State interface { Handle() string } type Context struct { state State } type ConcreteStateA struct{} type ConcreteStateB struct{} func (s *ConcreteStateA) Handle() string { return "State A" } func (s *ConcreteStateB) Handle() string { return "State B" } // 21. Strategy Pattern type Strategy interface { Execute() string } type ConcreteStrategyA struct{} type ConcreteStrategyB struct{} func (s *ConcreteStrategyA) Execute() string { return "Strategy A" } func (s *ConcreteStrategyB) Execute() string { return "Strategy B" } // 22. Template Method Pattern type AbstractClass interface { TemplateMethod() string PrimitiveOperation1() string PrimitiveOperation2() string } type ConcreteClass struct { PrimitiveOperation2 func() string } type ConcreteOperation2 struct { //PrimitiveOperation2 func() string } func (c *ConcreteClass) TemplateMethod() string { return c.PrimitiveOperation1() + " " + c.PrimitiveOperation2() } func (c *ConcreteClass) PrimitiveOperation1() string { return "Step 1" } func (c *ConcreteOperation2) PrimitiveOperation2() string { return "Step 2" } // 23. Visitor Pattern type Visitor interface { VisitConcreteElementA(*ConcreteElementA) VisitConcreteElementB(*ConcreteElementB) } type Element interface { Accept(Visitor) } type ConcreteElementA struct{} type ConcreteElementB struct{} func (e *ConcreteElementA) Accept(v Visitor) { v.VisitConcreteElementA(e) } func (e *ConcreteElementB) Accept(v Visitor) { v.VisitConcreteElementB(e) } type ConcreteVisitor struct{} func (v *ConcreteVisitor) VisitConcreteElementA(e *ConcreteElementA) { fmt.Println("Visited ConcreteElementA") } func (v *ConcreteVisitor) VisitConcreteElementB(e *ConcreteElementB) { fmt.Println("Visited ConcreteElementB") }