import (
"fmt"
"sync"
)
type BasketType int
const (
_ BasketType = iota
LARGEBASKET //Holds max of 20 balls
HUGEBASKET //Holds unlimited balls
)
type Ball struct {
Name string //RubberBall, TennisBall etc
Quantity int
basket BasketType
once sync.Once
BasketLocator
}
func (ball *Ball) GetBasket() BasketType {
ball.once.Do(func() { ball.LocateBasket(ball) })
//fmt.Println("Basket in GetBasket", ball.basket)
return ball.basket
}
type BasketLocator interface {
LocateBasket(ball *Ball)
}
type BasketLocatorImpl struct {
}
func (locator BasketLocatorImpl) LocateBasket(ball *Ball) {
fmt.Println("Calling basketlocator")
if ball.Quantity < 20 {
//fmt.Println("Setting large basket")
ball.basket = LARGEBASKET
return
}
//fmt.Println("Seting huge basket")
ball.basket = HUGEBASKET
}
func main() {
ball := Ball{
Name: "Tennis Ball",
Quantity: 2,
BasketLocator: BasketLocatorImpl{},
}
fmt.Println("Basket after first try ", ball.GetBasket())
ball.Quantity = 10
fmt.Println("Basket after second try ", ball.GetBasket())
ball.Quantity = 30
fmt.Println("Basket after thrid try ", ball.GetBasket())
}
In the above code, I am making sure that, we don’t unnecessarily call the LocateBasket function. It is called only once during the GetBasketCall. But if there is any attribute change (For eg. The quantity was changed to 30) then I wanted to make sure that when user calls GetBasket it internally calls LocateBasket function too.
In my example I had only one function, but if there is multiple attributes which needs to be re-calculated (based on attribute change) when their corresponding Getter Functions are getting called, what is the best approach to do the same.