implemented chain of responsibility
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
@@ -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)
|
||||
}
|
||||
})
|
||||
|
||||
}
|
Reference in New Issue
Block a user