design - Eliminating the duplication of methods -
is possible refactor following code eliminate duplication?
i want gameobject implement logic "update" task invoking different update handlers (like "afterupdate"). current version works, there 2 implementations of "update" , equal. afterupdate invoked on gameobject should operate on properties, afterupdate invoked on herogameobject should have access herogameobject's properties (like "health" example).
what can better? thank you.
package main import "fmt" type point struct { x, y int } /////////////////////// type gameobject struct { point title string status int ticks float32 spriteindex int } func (g *gameobject) update() { if g.ticks == 0 { g.spriteindex++ g.afterupdate() } } func (g *gameobject) afterupdate() { g.status = 0 //suppose meaningful fmt.println("gameobject afterupdate handler invoked") } /////////////////////// type herogameobject struct { gameobject health float32 } func (h *herogameobject) update() { if h.ticks == 0 { h.spriteindex++ h.afterupdate() } } func (h *herogameobject) afterupdate() { h.health-- //suppose meaningful *different*, using own properties, example "health" fmt.println("herogameobject afterupdate handler invoked") } /////////////////////// func main() { gameobject := &gameobject{ point: point{ x: 0, y: 0, }, title: "dummy object", status: 0, ticks: 0, spriteindex: 0, } heroobject := &herogameobject{ gameobject: gameobject{ point: point{ x: 0, y: 0, }, title: "hero object", status: 0, ticks: 0, spriteindex: 0, }, health: 0, } gameobject.update() heroobject.update() }
the output:
gameobject afterupdate handler invoked
herogameobject afterupdate handler invoked
updated i've come following solution , wonder think:
package main import "fmt" type point struct { x, y int } /////////////////////// type ihandler interface { afterupdate() } type gameobject struct { point title string status int ticks float32 spriteindex int handler ihandler } func (g *gameobject) sethandler(h ihandler) { g.handler = h } func (g *gameobject) update() { if g.ticks == 0 { g.spriteindex++ if g.handler != nil { g.handler.afterupdate() } } } //actually ihandler specific implementation number 1 func (g *gameobject) afterupdate() { g.status = 0 //suppose meaningful fmt.println("gameobject afterupdate handler invoked") } /////////////////////// type herogameobject struct { gameobject health float32 } // note, method commented out /* func (h *herogameobject) update() { if h.ticks == 0 { h.spriteindex++ h.afterupdate() } }*/ //actually ihandler specific implementation number 2 func (h *herogameobject) afterupdate() { h.health-- //suppose meaningful *different*, using own properties, example "health" fmt.println("herogameobject afterupdate handler invoked") } /////////////////////// func main() { gameobject := &gameobject{ point: point{ x: 0, y: 0, }, title: "dummy object", status: 0, ticks: 0, spriteindex: 0, } gameobject.sethandler(gameobject) //! heroobject := &herogameobject{ gameobject: gameobject{ point: point{ x: 0, y: 0, }, title: "hero object", status: 0, ticks: 0, spriteindex: 0, }, health: 0, } heroobject.sethandler(heroobject) //! gameobject.update() heroobject.update() }
http://play.golang.org/p/giwoknsszx
is okay have "gameobject.sethandler(gameobject)"?
how using flag function , base interface, this?
type basegameobject interface { ticks() int incspriteindex() afterupdate() } func updategameobject(o basegameobject) { if o.ticks() == 0 { o.incspriteindex() o.afterupdate() } } func (o *gameobject) ticks() int { return o.ticks } func (o *gameobject) incspriteindex() { o.spriteindex++ }
Comments
Post a Comment