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,只需提供接口要求的方法即可

Roboflow
Roboflow

一个为计算机视觉和机器学习提供工具和服务的平台

下载
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结构体相关大全,想了解更多内容,请阅读专题下面的文章。

490

2025.06.09

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

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

202

2025.07.04

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

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

1901

2023.10.19

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

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

656

2025.10.17

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

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

2387

2025.12.29

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

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

47

2026.01.19

Kotlin Android模块化架构与组件化开发实践
Kotlin Android模块化架构与组件化开发实践

本专题围绕 Kotlin 在 Android 应用开发中的架构实践展开,重点讲解模块化设计与组件化开发的实现思路。内容包括项目模块拆分策略、公共组件封装、依赖管理优化、路由通信机制以及大型项目的工程化管理方法。通过真实项目案例分析,帮助开发者构建结构清晰、易扩展且维护成本低的 Android 应用架构体系,提升团队协作效率与项目迭代速度。

24

2026.03.09

JavaScript浏览器渲染机制与前端性能优化实践
JavaScript浏览器渲染机制与前端性能优化实践

本专题围绕 JavaScript 在浏览器中的执行与渲染机制展开,系统讲解 DOM 构建、CSSOM 解析、重排与重绘原理,以及关键渲染路径优化方法。内容涵盖事件循环机制、异步任务调度、资源加载优化、代码拆分与懒加载等性能优化策略。通过真实前端项目案例,帮助开发者理解浏览器底层工作原理,并掌握提升网页加载速度与交互体验的实用技巧。

80

2026.03.06

Rust内存安全机制与所有权模型深度实践
Rust内存安全机制与所有权模型深度实践

本专题围绕 Rust 语言核心特性展开,深入讲解所有权机制、借用规则、生命周期管理以及智能指针等关键概念。通过系统级开发案例,分析内存安全保障原理与零成本抽象优势,并结合并发场景讲解 Send 与 Sync 特性实现机制。帮助开发者真正理解 Rust 的设计哲学,掌握在高性能与安全性并重场景中的工程实践能力。

187

2026.03.05

热门下载

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

精品课程

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

共32课时 | 6.1万人学习

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

共10课时 | 0.9万人学习

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

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