From a15b47e330277d9ec357d067f396d11e2ce1c863 Mon Sep 17 00:00:00 2001 From: "ugur.gungor" Date: Mon, 9 Oct 2017 20:05:57 +0300 Subject: [PATCH] behavioral/chain of responsibility: chain of responsibility pattern added. --- README.md | 2 +- behavioral/chain-of-responsibility/main.go | 49 +++++++++++++++++ behavioral/chain_of_responsibility.md | 64 ++++++++++++++++++++++ 3 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 behavioral/chain-of-responsibility/main.go create mode 100644 behavioral/chain_of_responsibility.md diff --git a/README.md b/README.md index 7d9f5f7..1f8bb61 100644 --- a/README.md +++ b/README.md @@ -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 | ✘ | diff --git a/behavioral/chain-of-responsibility/main.go b/behavioral/chain-of-responsibility/main.go new file mode 100644 index 0000000..b0074c0 --- /dev/null +++ b/behavioral/chain-of-responsibility/main.go @@ -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) +} diff --git a/behavioral/chain_of_responsibility.md b/behavioral/chain_of_responsibility.md new file mode 100644 index 0000000..e0a9496 --- /dev/null +++ b/behavioral/chain_of_responsibility.md @@ -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).