Skip to content

Instantly share code, notes, and snippets.

@naviat
Forked from egonelbre/gist:1311842
Created April 3, 2024 00:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save naviat/5aa38daecd620d5735b7d3996b2357e6 to your computer and use it in GitHub Desktop.
Save naviat/5aa38daecd620d5735b7d3996b2357e6 to your computer and use it in GitHub Desktop.
Design Patterns in GO
///////
// Warning, code untested
///////
type Thinger interface {
SomeMethod( arg bool ) bool
}
type RealThing struct {
state bool
}
func (r *RealThing) SomeMethod( arg bool ) bool {
r.state = r.state ^ arg
}
type UnrealThing struct {
state bool
}
func (r *UnrealThing) SomeMethod( arg bool ) bool {
r.state = r.state == arg
}
///////
// Abstract Factory ( Builder can be built using similar ideas )
type ThingerFactory interface {
CreateThing() Thinger
}
type RealThingFactory struct {
initial bool
}
func ( tf *RealThingFactory ) CreateThing() Thinger {
return &RealThing{ tf.initial }
}
// this can possibly also be replaced by a function
// type ThingerFactory func() *Thinger
tf := func() *Thinger{ return &RealThing{ true } }
thing := tf()
///////
// Pool
type ThingPool struct {
factory *ThingerFactory
unused chan *Thinger
}
func NewThingPool() *ThingPool {
tp := &ThingPool{}
tp.factory = &RealThingFactory{false}
tp.unused = make( chan Thinger )
return tp
}
func (tp *ThingPool) Get() *Thinger {
select {
case t := <- tp.thing:
return t;
default:
return tp.CreateThing()
}
}
func (tp *ThingPool) Put( t *Thinger) {
tp.unused <- t
}
///////
// Lazy Initialization
// Can be used for multiton by not providing access
// to the actual struct being created
type Things struct {
factory *ThingerFactory
things map[string] *Thinger
lock chan int // there is probably some better way of doing this
}
func NewThings() *Things {
th := &Things{}
th.lock = make( chan int, 1 )
th.factory = &RealThingFactory{false}
th.things = make( map[string] *Thinger )
th.lock <- 1
return th
}
func ( th *Things ) Get ( name string ) *Thinger {
<- th.lock
defer func(){ th.lock <- 1 }
if t, err := th.things[name]; err == nil {
return t
}
th := t.factory.CreateThing()
th.things[name] = th
return th
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment