diff --git a/behavioral/chain_of_responsibility.md b/behavioral/chain_of_responsibility.md new file mode 100644 index 0000000..5c0381f --- /dev/null +++ b/behavioral/chain_of_responsibility.md @@ -0,0 +1,12 @@ +# Observer Pattern + +The [chain of responsibility pattern](https://en.wikipedia.org/wiki/Chain-of-responsibility_pattern) is a design pattern consisting in a series of independent processes that will run in in sequence. It gives power to rearange the sequence or add new processes at the end of it without changing its structure. + +## Implementation + +Each process in the chain must implement a function to be executed and call the next process at the end. +It will call each process recursivelly until there is no more porcesses in the chain of responsibility. + +## Usage + +For usage, see [chain_of_responsibility/main.go](chain_of_responsibility/main.go) or [view in the Playground](https://play.golang.org/p/XA2v0XlenAi). diff --git a/behavioral/chain_of_responsibility/main.go b/behavioral/chain_of_responsibility/main.go new file mode 100644 index 0000000..202cd81 --- /dev/null +++ b/behavioral/chain_of_responsibility/main.go @@ -0,0 +1,91 @@ +package main + +import "fmt" + +type task interface { + execute() + setNext(task) +} + +type turnOnLights struct { + next task +} + +func (turnOnLights *turnOnLights) execute() { + fmt.Println("Turning the lights on...") + if turnOnLights.next != nil { + turnOnLights.next.execute() + } +} + +func (turnOnLights *turnOnLights) setNext(next task) { + turnOnLights.next = next +} + +type turnOnComputer struct { + next task +} + +func (turnOnComputer *turnOnComputer) execute() { + fmt.Println("Turning the computer on...") + if turnOnComputer.next != nil { + turnOnComputer.next.execute() + } +} + +func (turnOnComputer *turnOnComputer) setNext(next task) { + turnOnComputer.next = next +} + +type openCodeEditor struct { + next task +} + +func (openCodeEditor *openCodeEditor) execute() { + fmt.Println("Opening the code editor...") + if openCodeEditor.next != nil { + openCodeEditor.next.execute() + } +} + +func (openCodeEditor *openCodeEditor) setNext(next task) { + openCodeEditor.next = next +} + +type code struct { + next task +} + +func (code *code) execute() { + fmt.Println("Start coding in go...") + if code.next != nil { + code.next.execute() + } +} + +func (code *code) setNext(next task) { + code.next = next +} + +func main() { + turnOnLights := &turnOnLights{} + turnOnComputer := &turnOnComputer{} + openCodeEditor := &openCodeEditor{} + code := &code{} + + turnOnLights.setNext(turnOnComputer) + turnOnComputer.setNext(openCodeEditor) + openCodeEditor.setNext(code) + + turnOnLights.execute() + // Out: + // Turning the lights on... + // Turning the computer on... + // Opening the code editor... + // Start coding in go... + + openCodeEditor.execute() + // Out: + // Opening the code editor... + // Start coding in go... +}