消除方法的重复

时间:2014-12-16 13:09:21

标签: go

是否可以重构以下代码以消除重复?

我希望我的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)”?

1 个答案:

答案 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++
}