是否可以重构以下代码以消除重复?
我希望我的GameObject实现“更新”任务的逻辑,调用不同的更新处理程序(比如我的“AfterUpdate”)。当前版本有效,但有两个“更新”实现,它们是相同的。 在GameObject上调用的AfterUpdate应该对其属性进行操作,在HeroGameObject上调用的AfterUpdate应该可以访问HeroGameObject的属性(例如“健康”)。
我能做得更好吗?谢谢。
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 it does something 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 it does something meaningful but *different*, using its own properties, for 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()
}
输出:
调用GameObject afterUpdate处理程序
调用HeroGameObject afterUpdate处理程序
已更新 我想出了以下解决方案,我想知道你的想法是什么:
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 it is IHandler specific implementation number one
func (g *GameObject) afterUpdate() {
g.status = 0 //suppose it does something meaningful
fmt.Println("GameObject afterUpdate handler invoked")
}
///////////////////////
type HeroGameObject struct {
GameObject
health float32
}
// note, this method is commented out
/*
func (h *HeroGameObject) Update() {
if h.ticks == 0 {
h.spriteIndex++
h.AfterUpdate()
}
}*/
//actually it is IHandler specific implementation number two
func (h *HeroGameObject) afterUpdate() {
h.health-- //suppose it does something meaningful but *different*, using its own properties, for 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
是否可以使用“gameObject.SetHandler(gameObject)”?
答案 0 :(得分:5)
使用标志功能和基本界面怎么样?
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++
}