Messaging Patterns Fan-In Messaging Patterns Fan-In is a messaging pattern used to create a funnel for work amongst workers (clients: source, server: destination).
We can model fan-in using the Go channels.
// Merge different channels in one channel func Merge(cs ...<-chan int) <-chan int { var wg sync.WaitGroup out := make(chan int) // Start an send goroutine for each input channel in cs. send // copies values from c to out until c is closed, then calls wg.
Synchronization Patterns Semaphore Pattern A semaphore is a synchronization pattern/primitive that imposes mutual exclusion on a limited number of resources.
Implementation package semaphore var ( ErrNoTickets = errors.New("semaphore: could not aquire semaphore") ErrIllegalRelease = errors.New("semaphore: can't release the semaphore without acquiring it first") ) // Interface contains the behavior of a semaphore that can be acquired and/or released. type Interface interface { Acquire() error Release() error } type implementation struct { sem chan struct{} timeout time.
Behavioral Patterns Observer Pattern The observer pattern allows a type instance to “publish” events to other type instances (“observers”) who wish to be updated when a particular event occurs.
Implementation In long-running applications—such as webservers—instances can keep a collection of observers that will receive notification of triggered events.
Implementations vary, but interfaces can be used to make standard observers and notifiers:
type ( // Event defines an indication of a point-in-time occurrence.
Structural Patterns Decorator Pattern Decorator structural pattern allows extending the function of an existing object dynamically without altering its internals.
Decorators provide a flexible method to extend functionality of objects.
Implementation LogDecorate decorates a function with the signature func(int) int that manipulates integers and adds input/output logging capabilities.
type Object func(int) int func LogDecorate(fn Object) Object { return func(n int) int { log.Println("Starting the execution with the integer", n) result := fn(n) log.
Introduction Recently I started a series of articles about Gang of Four Design Patterns and their adoption in Golang. They made a lot of noise in the community. I read a lot of contradictionary opionions whether should be used or not. I am publishing those articles as show case how the common design patterns can be adopted and implemented in Golang. I don’t encourage or promote their usage. Every developer has own style of programming, architecture desing and problem solving solutions.