/////// // 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 }