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