1
0
mirror of https://github.com/tmrts/go-patterns.git synced 2024-11-25 14:36:06 +03:00

behavioral/chain of responsibility: chain of responsibility pattern added.

This commit is contained in:
ugur.gungor 2017-10-09 20:05:57 +03:00
parent f978e42036
commit a15b47e330
3 changed files with 114 additions and 1 deletions

View File

@ -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 | ✘ |

View File

@ -0,0 +1,49 @@
package main
import (
"fmt"
)
type (
//Data will be processed by chain
Data struct {
Data string
}
//Handler defines an interface for handling requests
Handler interface {
Handle(data *Data)
}
)
//ConcreteAHandler implements Handler interface
type ConcreteAHandler struct {
//Next element in the chain
Successor Handler
}
func (ca ConcreteAHandler) Handle(data *Data) {
fmt.Printf("%s handled by Concrete A\n", data.Data)
if ca.Successor != nil {
ca.Successor.Handle(data)
}
}
//ConcreteBHandler implements Handler interface
type ConcreteBHandler struct {
Successor Handler
}
func (cb ConcreteBHandler) Handle(data *Data) {
fmt.Printf("%s handled by Concrete B\n", data.Data)
if cb.Successor != nil {
cb.Successor.Handle(data)
}
}
func main() {
data := &Data{Data: "Example Data"}
var concreteBHandler Handler = ConcreteBHandler{}
var concreteAHandler Handler = ConcreteAHandler{Successor: concreteBHandler}
concreteAHandler.Handle(data)
}

View File

@ -0,0 +1,64 @@
# Chain Of Responsibility Pattern
Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it. [Source](http://www.dofactory.com/net/chain-of-responsibility-design-pattern)
## Implementation
```go
type (
//Data will be processed by chain
Data struct {
Data string
}
//Handler defines an interface for handling requests
Handler interface {
Handle(data *Data)
}
)
//ConcreteAHandler implements Handler interface
type ConcreteAHandler struct {
//Next element in the chain
Successor Handler
}
func (ca ConcreteAHandler) Handle(data *Data) {
fmt.Printf("%s handled by Concrete A\n", data.Data)
if ca.Successor != nil {
ca.Successor.Handle(data)
}
}
//ConcreteBHandler implements Handler interface
type ConcreteBHandler struct {
Successor Handler
}
func (cb ConcreteBHandler) Handle(data *Data) {
fmt.Printf("%s handled by Concrete B\n", data.Data)
if cb.Successor != nil {
cb.Successor.Handle(data)
}
}
```
We have created an interface for handling request. Then we have created 2 concretes struct implementing Handler. Each handler writes own message using by data.
```go
func main() {
data := &Data{Data: "Example Data"}
var concreteBHandler Handler = ConcreteBHandler{}
var concreteAHandler Handler = ConcreteAHandler{Successor: concreteBHandler}
concreteAHandler.Handle(data)
}
```
Client initializes chain. Objects in the chain process data in order.
## Usage
For usage, see [chain-of-responsibility/main.go](chain-of-responsibility/main.go) or [view in the Playground](https://play.golang.org/p/tN8LZvjNpP).