0

0

如何通过接口与组合消除 Go 中游戏对象的重复 Update 方法

聖光之護

聖光之護

发布时间:2026-01-01 13:39:23

|

974人浏览过

|

来源于php中文网

原创

如何通过接口与组合消除 Go 中游戏对象的重复 Update 方法

本文介绍如何利用 go 的接口抽象与函数复用机制,消除 gameobject 及其子类型中重复的 update 实现,同时保持各类型对自身字段(如 health)的专属访问能力。

在 Go 这类不支持传统继承的语言中,当多个结构体需共享相同控制逻辑(如 Update() 的调度流程),但又需各自实现差异化业务行为(如 AfterUpdate() 对不同字段的操作)时,直接复制 Update 方法不仅违反 DRY 原则,更增加维护成本和出错风险。

上述代码中,GameObject 和 HeroGameObject 的 Update 方法完全一致:检查 ticks == 0 → 自增 spriteIndex → 调用 AfterUpdate()。真正的差异仅在于 AfterUpdate() 的具体实现及其所操作的字段(status vs health)。因此,将通用调度逻辑上提为独立函数、将差异化行为抽象为接口方法,是最符合 Go 习惯的解法

✅ 推荐方案:接口 + 通用更新函数

我们定义一个轻量接口 BaseGameObject,仅声明三个必需行为:获取 ticks 值、更新 sprite 索引、执行后置逻辑:

type BaseGameObject interface {
    Ticks() float32   // 注意:原代码中 ticks 是 float32,接口应保持类型一致
    IncSpriteIndex()
    AfterUpdate()
}

接着,将重复的调度逻辑提取为一个纯函数:

func UpdateGameObject(o BaseGameObject) {
    if o.Ticks() == 0 {
        o.IncSpriteIndex()
        o.AfterUpdate()
    }
}

然后,让 GameObject 和 HeroGameObject 分别实现该接口——无需重写 Update,只需提供接口要求的方法即可

Facetune
Facetune

一款在线照片和视频编辑工具,允许用户创建AI头像

下载
func (g *GameObject) Ticks() float32       { return g.ticks }
func (g *GameObject) IncSpriteIndex()      { g.spriteIndex++ }
func (g *GameObject) AfterUpdate()         {
    g.status = 0
    fmt.Println("GameObject afterUpdate handler invoked")
}

func (h *HeroGameObject) Ticks() float32    { return h.ticks } // 继承自嵌入字段,可直接转发
func (h *HeroGameObject) IncSpriteIndex()   { h.spriteIndex++ }
func (h *HeroGameObject) AfterUpdate()      {
    h.health-- // ✅ 直接访问 HeroGameObject 特有字段
    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: 100,
    }

    UpdateGameObject(gameObject) // 统一入口,自动分发到对应 AfterUpdate
    UpdateGameObject(heroObject)
}

⚠️ 关于“self-set-handler”方案的说明

原问题中提出的 SetHandler(gameObject) 方案虽能工作,但存在明显缺陷:

  • 语义混乱:GameObject 同时作为数据容器和处理器,职责不清;
  • 强制耦合:每个实例必须手动调用 SetHandler(this),易遗漏且破坏封装;
  • 类型安全弱化:IHandler 接口需暴露内部方法(如 afterUpdate),违背封装原则,且小写方法无法被外部包实现。

相比之下,BaseGameObject 接口方案:

  • ✅ 完全零冗余:Update 逻辑只写一次;
  • ✅ 类型安全:编译器确保所有 UpdateGameObject 参数都满足行为契约;
  • ✅ 高度灵活:新增游戏对象类型(如 EnemyGameObject)只需实现接口,无需修改调度逻辑;
  • ✅ 符合 Go 设计哲学:组合优于继承,接口描述行为而非类型。

总结

消除重复的关键不是“把逻辑塞进父类”,而是识别共性行为、抽象为接口、将控制流外置为函数。这种模式在游戏开发、事件驱动系统、状态机等场景中广泛适用。记住 Go 的信条:“Accept interfaces, return structs.” —— 让函数依赖接口,让具体类型专注实现,代码自然清晰、健壮、可扩展。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

220

2025.06.09

golang结构体方法
golang结构体方法

本专题整合了golang结构体相关内容,请阅读专题下面的文章了解更多。

190

2025.07.04

硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

1072

2023.10.19

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

148

2025.10.17

php8.4实现接口限流的教程
php8.4实现接口限流的教程

PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

1078

2025.12.29

java接口相关教程
java接口相关教程

本专题整合了java接口相关内容,阅读专题下面的文章了解更多详细内容。

13

2026.01.19

c++ 根号
c++ 根号

本专题整合了c++根号相关教程,阅读专题下面的文章了解更多详细内容。

70

2026.01.23

c++空格相关教程合集
c++空格相关教程合集

本专题整合了c++空格相关教程,阅读专题下面的文章了解更多详细内容。

72

2026.01.23

yy漫画官方登录入口地址合集
yy漫画官方登录入口地址合集

本专题整合了yy漫画入口相关合集,阅读专题下面的文章了解更多详细内容。

297

2026.01.23

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Go 教程
Go 教程

共32课时 | 4.2万人学习

Go语言实战之 GraphQL
Go语言实战之 GraphQL

共10课时 | 0.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号