Skip to content

Instantly share code, notes, and snippets.

@drgomesp
Last active December 14, 2016 14:16
Show Gist options
  • Save drgomesp/b2f0428fe58c03bfc1d2c47a97dec8d8 to your computer and use it in GitHub Desktop.
Save drgomesp/b2f0428fe58c03bfc1d2c47a97dec8d8 to your computer and use it in GitHub Desktop.
Lazy object initialization in Go
package main
import (
"log"
"math/rand"
"time"
)
type A struct{}
type B struct{}
func (a *A) bar() {}
func (b *B) bar() {}
// ServiceInterface that will be implemented by both the concrete service and the service proxy
type ServiceInterface interface {
foo()
}
// Service with some dependencies
type Service struct {
a *A
b *B
}
func (s *Service) foo() {
s.a.bar()
s.b.bar()
log.Printf("Service::foo()")
}
// ServiceProxy for lazy initialization of Service
type ServiceProxy struct {
*Service
initialized bool
initializer func(a *A, b *B) *Service
}
// NewServiceProxy initializer function (should be blazing fast)
func NewServiceProxy(initializer func(a *A, b *B) *Service) *ServiceProxy {
start := time.Now()
elapsed := time.Since(start)
log.Printf("NewServiceProxy() took %s", elapsed)
return &ServiceProxy{
initializer: initializer,
}
}
func (p *ServiceProxy) foo() {
if p.initialized == false {
p.initialized = true
// Container will be responsible for initializing the dependencies
a := &A{}
b := &B{}
p.Service = p.initializer(a, b)
}
p.Service.foo()
}
// NewService initializer function
func NewService(a *A, b *B) *Service {
// Some random sleep to simulate heavy initialization
start := time.Now()
time.Sleep(time.Duration(rand.Intn(1500)) * time.Millisecond)
elapsed := time.Since(start)
log.Printf("NewService() took %s", elapsed)
return &Service{
a: a,
b: b,
}
}
// Some function that takes a service interface pointer
func bar(service ServiceInterface) {
service.foo()
}
func main() {
a := &A{}
b := &B{}
service := NewService(a, b)
proxy := NewServiceProxy(NewService)
bar(service)
bar(proxy)
}
@drgomesp
Copy link
Author

Output:

2016/12/14 18:08:43 NewService() took 583.813466ms
2016/12/14 18:08:43 NewServiceProxy() took 54ns
2016/12/14 18:08:43 Service::foo()
2016/12/14 18:08:43 NewService() took 391.750717ms
2016/12/14 18:08:43 Service::foo()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment