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