Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Behavioral - Chain of Responsibility #100

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ A curated collection of idiomatic design & application patterns for Go language.

| Pattern | Description | Status |
|:-------:|:----------- |:------:|
| [Chain of Responsibility](/behavioral/chain_of_responsibility.md) | Avoids coupling a sender to receiver by giving more than object a chance to handle the request | |
| [Chain of Responsibility](/behavioral/chain_of_responsibility.md) | Avoids coupling a sender to receiver by giving more than object a chance to handle the request | |
| [Command](/behavioral/command.md) | Bundles a command and arguments to call later | ✘ |
| [Mediator](/behavioral/mediator.md) | Connects objects and acts as a proxy | ✘ |
| [Memento](/behavioral/memento.md) | Generate an opaque token that can be used to go back to a previous state | ✘ |
Expand Down
12 changes: 12 additions & 0 deletions behavioral/chain_of_responsibility.md
Original file line number Diff line number Diff line change
@@ -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).
91 changes: 91 additions & 0 deletions behavioral/chain_of_responsibility/main.go
Original file line number Diff line number Diff line change
@@ -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...
}