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:
parent
f978e42036
commit
a15b47e330
@ -36,7 +36,7 @@ A curated collection of idiomatic design & application patterns for Go language.
|
|||||||
|
|
||||||
| Pattern | Description | Status |
|
| 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 | ✘ |
|
| [Command](/behavioral/command.md) | Bundles a command and arguments to call later | ✘ |
|
||||||
| [Mediator](/behavioral/mediator.md) | Connects objects and acts as a proxy | ✘ |
|
| [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 | ✘ |
|
| [Memento](/behavioral/memento.md) | Generate an opaque token that can be used to go back to a previous state | ✘ |
|
||||||
|
49
behavioral/chain-of-responsibility/main.go
Normal file
49
behavioral/chain-of-responsibility/main.go
Normal 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)
|
||||||
|
}
|
64
behavioral/chain_of_responsibility.md
Normal file
64
behavioral/chain_of_responsibility.md
Normal 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).
|
Loading…
Reference in New Issue
Block a user