implemented chain of responsibility

This commit is contained in:
ismayilmalik 2018-01-01 21:29:51 +03:00
parent 6c870679a4
commit 1328860453
3 changed files with 122 additions and 0 deletions

View File

@ -9,6 +9,7 @@
- [Structural patterns](#structural-patterns) - [Structural patterns](#structural-patterns)
- [Composition](#composition) - [Composition](#composition)
- [Behavioral patterns](#behavioral-patterns) - [Behavioral patterns](#behavioral-patterns)
- [Chain of responsibility](#chain-of-responsibility)
- [Concurrency patterns](#concurrency-patterns) - [Concurrency patterns](#concurrency-patterns)
--- ---
@ -39,6 +40,10 @@ between objects. Behavio ral patterns describe not just patterns of objects or c
but also the patterns of communication between them. These patterns characterize but also the patterns of communication between them. These patterns characterize
complex control flow that's difficult to follow at run-time. They shift your focus away complex control flow that's difficult to follow at run-time. They shift your focus away
from flow of control to let you concent ratejust on the way objects are interconnected. from flow of control to let you concent ratejust on the way objects are interconnected.
### Chain of responsibility
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.
## Concurrency patterns ## Concurrency patterns
Pattenrs for concurrent work and parallel execution in Go. Pattenrs for concurrent work and parallel execution in Go.

View File

@ -0,0 +1,81 @@
package chain_of_responsibility
import (
"errors"
"fmt"
"encoding/json"
)
type Handler interface {
Handle(interface{}) error
}
type Book struct {
Title string
Author string
}
func (b Book) String() string {
return fmt.Sprintf("%b", b)
}
type Deserializer struct {
next Handler
}
func (h *Deserializer) Handle(data interface{}) error {
var book Book
bytes, ok := data.([]byte)
if !ok {
return errors.New("Unsupported type!")
}
if err := json.Unmarshal(bytes, &book); err != nil {
return err
}
if h.next != nil {
return h.next.Handle(book)
}
return nil
}
type Logger struct {
next Handler
}
func (h *Logger) Handle(data interface{}) error {
book, ok := data.(Book)
if !ok {
return errors.New("Argument is not a Book instance")
}
fmt.Println("Book received! Titlle: '%s' Author: '%s", book.Title, book.Author)
if h.next != nil {
return h.next.Handle(book)
}
return nil
}
type BookDb struct {
store map[string]Book
next Handler
}
func (h *BookDb) Handle(data interface{}) error {
book, ok := data.(Book)
if !ok {
return errors.New("Argument is not a Book instance")
}
h.store[book.Title]=book
if h.next != nil {
return h.next.Handle(book)
}
return nil
}

View File

@ -0,0 +1,36 @@
package chain_of_responsibility
import (
"encoding/json"
"testing"
)
func TestCORPattern(t *testing.T) {
book := Book{"Go design patterns", "Ismayil Malik"}
bytes, _ := json.Marshal(book)
bookDb := &BookDb{
make(map[string]Book),
nil,
}
logger := &Logger{
next: bookDb,
}
chain := &Deserializer{
next: logger,
}
t.Run(`It will be unmurshalled on deserializer handler then will be logged
on logger handler and at the end will be presisted by third handler`, func(t *testing.T) {
err := chain.Handle(bytes)
if err != nil {
t.Fatalf("Something went wrong: %s", err.Error())
}
storedBook := bookDb.store[book.Title]
if storedBook != book {
t.Errorf("Expected %b but got %b", book, storedBook)
}
})
}