找回密码
 立即注册
搜索
查看: 4489|回复: 49

[软件] 求助:面向对象 与 面向过程 及全局变量

[复制链接]
     
发表于 2024-12-13 14:36 | 显示全部楼层 |阅读模式
C++环境,编写一个打怪物的游戏,分为 主角 和 怪物。
这其中肯定涉及到主角和怪物的一系列数据:精灵图片的高宽、位置、速度、生命值、……

如果采用(面向过程)全局变量方式,则这些数据可以直接使用。程序清单也简洁漂亮。

而推荐的面向对象方式,需要设置两个类:主角类CLASS、怪物类CLASS
类内各自的数据成员(高宽、位置、速度)都是private的。还必须添加很多的SetPosition(int X, int Y) 、getPosition()……成员函数,程序长度增加很多,代码显得繁琐、凌乱。在类外使用一个变量,必须调用一次函数,才能得到想要的值。为什么推荐这种脱裤子放屁的方法?

若是开发操作系统、PhotoShop这些大型软件,倒还可以理解。

回复

使用道具 举报

     
发表于 2024-12-13 14:42 | 显示全部楼层
都是工具,看你需求你自己决定。当然后期加需求的时候别再来发一贴哭诉
回复

使用道具 举报

     
发表于 2024-12-13 14:50 | 显示全部楼层
超过100种怪物时,你就知道面向对象的好了
回复

使用道具 举报

发表于 2024-12-13 14:54 | 显示全部楼层
本帖最后由 overflowal 于 2024-12-13 14:59 编辑

不要太在意OOP的编程范式,现在新的语言都不乐意玩这套是有原因的。
继承,多态这一套听起来非常美好,但是实际上一上手就可能让你代码整个僵住。
(当然也不是让你完全不抽象,就面条代码写到底
回复

使用道具 举报

     
发表于 2024-12-13 15:34 来自手机 | 显示全部楼层
感觉光面向对象也没啥用,得学点设计模式

—— 来自 鹅球 v3.3.92
回复

使用道具 举报

     
发表于 2024-12-13 16:02 | 显示全部楼层
set_variable和get_variable使用的目的是为了保证变量类型的invariant,变化中保持一些东西不变,以及一些is_valid的保证。
当不需要这些不变形和有效性的验证时,给予变量字段field的访问权。

如果你发现你的包装产生了非高效简洁的代码,那么这个包装不适宜场景。具体的是你的类型编写的问题,或者是范氏本身的问题,就需要仔细考量了。
回复

使用道具 举报

     
发表于 2024-12-13 16:17 来自手机 | 显示全部楼层
你整个游戏只有一个角色和一个怪物吗,还是你每个怪物都建一个类
回复

使用道具 举报

发表于 2024-12-13 16:38 | 显示全部楼层
你详细分析了需求和架构后如果仍然觉得没必要oop,那就是没必要
要么是你的能力,要么是你的程序还没有到应该oop的程度

当你开始后悔并考虑重构时,那才是oop ready的时候
回复

使用道具 举报

     
发表于 2024-12-13 17:47 | 显示全部楼层
本帖最后由 BRRM 于 2024-12-13 17:55 编辑
还必须添加很多的SetPosition(int X, int Y) 、getPosition()……成员函数,程序长度增加很多,代码显得繁琐、凌乱。在类外使用一个变量,必须调用一次函数,才能得到想要的值。为什么推荐这种脱裤子放屁的方法?

防止你乱改,如果你可以随意的赋值,那你就没办法在赋值的过程中进行错误检查。万一你写成 player.x="123",那不是出bug了吗?

(当然,有的语言像 python 可以在语言层面上解决这个问题,直接进行优雅的读取、修改,但是底层仍然是有一个函数进行错误检查。)

不过我觉得你这个问题跟面向对象其实没啥关系。

“面向对象”或者“面向过程”都是一种思维方式,也是一种看待问题的角度。对于计算机来说,不存在所谓的面向对象还是面向过程。

为什么面向对象流行,单纯是面向对象的编码方式对于大多数人来说更方便、更容易让人理解,仅此而已。
回复

使用道具 举报

     
发表于 2024-12-13 17:58 | 显示全部楼层
说得好 但是我的项目有二十万个对象 分成四十大类 六百个小类 同时有20个人写代码 业务逻辑天天变
每天参数不一样 需要根据基础架构持续扩展以及重写
回复

使用道具 举报

     
发表于 2024-12-13 18:12 | 显示全部楼层
一是规模大了面向过程无法维护,二是很重要的一点,这种设计方便团队合作,只需要几个厉害的人抽象好框架,然后找一堆菜逼填工作量就行
回复

使用道具 举报

     
发表于 2024-12-13 18:59 来自手机 | 显示全部楼层
没错,我推荐你立即使用C
顺便,用C出现问题九成九是你自己哪里没写对,请仔细排查,少发帖问

—— 来自 鹅球 v3.1.88.3
回复

使用道具 举报

     
发表于 2024-12-13 20:50 来自手机 | 显示全部楼层
本帖最后由 henvelleng 于 2024-12-13 21:02 编辑

一般批判面向对象的点是继承,你这又是哪一出啊?

c语言也是用结构体封装对象的,把函数指针成员塞进对象里调用,也有构造函数和析构函数的等价版本,这你也不知道吗?

—— 来自 鹅球 v3.1.88.3
回复

使用道具 举报

头像被屏蔽
     
发表于 2024-12-13 21:49 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复

使用道具 举报

     
发表于 2024-12-13 22:12 | 显示全部楼层
只要你做的东西足够简单,那么面向过程写到底肯定能做,反正面对的也就那么几个东西。
但是东西一多起来……不抽象出来做你就哭吧。
回复

使用道具 举报

     
发表于 2024-12-14 09:05 来自手机 | 显示全部楼层
和项目复杂度相关,如果有效代码过万行的话,总是会自己开始封装的。你的游戏如果行数不多的话确实可以不做封装

—— 来自 鹅球 v3.1.90
回复

使用道具 举报

     
发表于 2024-12-14 09:59 | 显示全部楼层
17年的号问这个问题感觉有点怪,说真的超过一万行代码的项目,你不用面向对象都会很痛苦。说到底面向对象是为了程序的可维护性和可复用性。不然复杂度高起来,面向过程编程你是玩不来的。

还有一般做游戏的话,需要掌握几个常见设计模式:比如工厂模式、单例模式、观察者模式、原型模式等等。你现在还是先找个项目变抄边做最合适。
回复

使用道具 举报

     
发表于 2024-12-14 10:31 来自手机 | 显示全部楼层
写游戏直接ecs吧,还面个啥对象
回复

使用道具 举报

     
发表于 2024-12-14 10:47 | 显示全部楼层
问一下LZ写过多久的代码,有没有和别人一起写代码的经验。
这种问题在我看来应该是非常自然的,你写多了代码自然会理解这些工程实践的优缺点。
回复

使用道具 举报

     
发表于 2024-12-14 11:15 来自手机 | 显示全部楼层
lz应该是想做游戏所以自学的编程吧来自: iPhone客户端
回复

使用道具 举报

     
发表于 2024-12-14 12:04 | 显示全部楼层
所有设计模式都可以说只是工程上的最佳实践方案
当你的程序还没能算是工程的时候,确实是没必要管的
如果是做游戏的话,就直接别管这些先撸,先看到结果才有继续的动力和方向
回复

使用道具 举报

     
发表于 2024-12-14 12:14 | 显示全部楼层
本帖最后由 raimouse 于 2024-12-14 12:16 编辑

借楼问一句
我自己写个python玩具,其实也就几百行的水平很简单
函数之间交换信息用了全局变量但是总感觉不是很好的处理方案
但是函数不是固定顺序执行,也不好直接用返回值啥的来传递信息
还有啥简单方便的方案么
回复

使用道具 举报

     
发表于 2024-12-14 12:21 来自手机 | 显示全部楼层
raimouse 发表于 2024-12-14 12:14
借楼问一句
我自己写个python玩具,其实也就几百行的水平很简单
函数之间交换信息用了全局变量但是总感觉不 ...

数据多就封装一个缓冲池,当然其实也是全局,封装了可以加上存取接口控制读写。
程序规模小没必要,就全局变量也行

—— 来自 HUAWEI OCE-AN50, Android 12上的 S1Next-鹅版 v2.5.4
回复

使用道具 举报

     
发表于 2024-12-14 12:45 | 显示全部楼层
raimouse 发表于 2024-12-14 12:14
借楼问一句
我自己写个python玩具,其实也就几百行的水平很简单
函数之间交换信息用了全局变量但是总感觉不 ...

一般上一个简单的 class 呗
  1. class App:
  2.     def __init__(self):
  3.          self.var0 = None
  4.          self.var1 = None

  5.     def action0(self):
  6.          self.var0 = "Hello My App"

  7.     def action1(self):
  8.          self.var1 = self.var0 + ", bye."

  9.     def show(self):
  10.         print(self.var1)

  11. if __name__ == "__main__":
  12.     app = App()
  13.     app.action0()
  14.     app.action1()
  15.     app.show()
复制代码



回复

使用道具 举报

     
发表于 2024-12-14 13:09 | 显示全部楼层
全局变量的坏处是你不知道什么时候 那个地方改了. 特别是多人协作的情况下.

软件工程化是特别复杂的东西. 没有一个设计模式是通杀的.
回复

使用道具 举报

     
发表于 2024-12-14 13:38 来自手机 | 显示全部楼层
无论是游戏还是工控,状态机都是很好用的东西。全局变量即使不谈软件工程和可读性可扩展性,在并发、可重入等问题上也是噩梦

—— 来自 鹅球 v3.1.88.3
回复

使用道具 举报

     
发表于 2024-12-14 13:47 来自手机 | 显示全部楼层
raimouse 发表于 2024-12-14 12:14
借楼问一句
我自己写个python玩具,其实也就几百行的水平很简单
函数之间交换信息用了全局变量但是总感觉不 ...

没有好办法,要么把函数做得更内聚,不依赖外部数据,要么提前规划好有哪些全局状态

—— 来自 鹅球 v3.0.86-alpha
回复

使用道具 举报

     
发表于 2024-12-14 15:01 | 显示全部楼层
raimouse 发表于 2024-12-14 12:14
借楼问一句
我自己写个python玩具,其实也就几百行的水平很简单
函数之间交换信息用了全局变量但是总感觉不 ...

你就自己写个小程序玩那用很多全局变量当然不是不行,只要你自己还记得处理逻辑不会乱掉就行
但要是大型工程或者多人协作,你有一大堆全局变量那玩意发现值不对都不知道是那里改的
再比如大型工程那要保证质量就得搞单元测试,不然随便改点什么就得重新手动测那能把人逼疯了。但是如果你程序里一堆全局变量那单元测试就很难写了
很多东西比如单元测试、LOG、Accessor之类的对写着玩的小程序来说可能累赘或者多余,但是稍大一点的工程不能没有,不然根本没法debug
像全局变量如果必须用的话会包装成singleton,也是为了方便测试,还有限制调用者修改什么的

话说回来只有几百行又不是固定顺序执行是怎么回事,很小的UI程序或者多线程吗
回复

使用道具 举报

     
发表于 2024-12-14 16:29 | 显示全部楼层
RTLordCaptain 发表于 2024-12-14 15:01
你就自己写个小程序玩那用很多全局变量当然不是不行,只要你自己还记得处理逻辑不会乱掉就行
但要是大型 ...

是的,我做了个UI程序
目前先弹一个文件选择框选择文件
选择完成后把文件路径写进全局变量
后续选确定执行就调用新函数,从全局变量读路径进行操作
选取消就重置全局变量,也不会执行新函数
所以函数执行顺序不是固定的
回复

使用道具 举报

     
发表于 2024-12-14 16:31 来自手机 | 显示全部楼层
首先,面向对象是在你整个业务确定不会有改动的情况下去写的,等你发现要对整个功能有频繁改动的时候你就会觉得很麻烦,比如 ddd 架构,一个简单的对象为了对象而对象,面向过程就好多了,代码虽然冗余且差,但好修改
回复

使用道具 举报

     
发表于 2024-12-14 20:06 来自手机 | 显示全部楼层
raimouse 发表于 2024-12-14 12:14
借楼问一句
我自己写个python玩具,其实也就几百行的水平很简单
函数之间交换信息用了全局变量但是总感觉不 ...

协程。函数之间交换信息,意味的是对等调用,而不是主从调用。

—— 来自 鹅球 v3.1.89
回复

使用道具 举报

     
发表于 2024-12-14 21:22 来自手机 | 显示全部楼层
raimouse 发表于 2024-12-14 12:14
借楼问一句
我自己写个python玩具,其实也就几百行的水平很简单
函数之间交换信息用了全局变量但是总感觉不 ...

把全部函数放一个类里面,全局变量放成员变量,然后观察有哪些变量是只有哪些函数用的,而这些函数和成员变量能不能组成一个合理的类,能的话就抽出来做子类。
回复

使用道具 举报

     
发表于 2024-12-14 22:12 | 显示全部楼层
本帖最后由 格林达姆 于 2024-12-14 22:16 编辑
raimouse 发表于 2024-12-14 12:14
借楼问一句
我自己写个python玩具,其实也就几百行的水平很简单
函数之间交换信息用了全局变量但是总感觉不 ...

业务和数据分离,所有数据读写都放个独立的工具类里通过接口访问。这样多线程也好去控制
回复

使用道具 举报

     
发表于 2024-12-14 23:09 | 显示全部楼层
格林达姆 发表于 2024-12-14 22:12
业务和数据分离,所有数据读写都放个独立的工具类里通过接口访问。这样多线程也好去控制 ...

目前看下来好像多数意见都是封装一个专门的缓存类用来控制变量读写
等周一上班了我在研究下
谢谢楼里各位前辈的意见
回复

使用道具 举报

     
发表于 2024-12-14 23:35 | 显示全部楼层
raimouse 发表于 2024-12-14 23:09
目前看下来好像多数意见都是封装一个专门的缓存类用来控制变量读写
等周一上班了我在研究下
谢谢楼里各位 ...

说实话除非是有深入继续学习的想法,不然就直接全局变量也没什么问题

平时写写脚本或玩具怎么舒服怎么来就行,真正想写正经程序再来搞这些范式。
像工程代码,一个大点的类几百行代码都很正常,可能你的全局变量就相当于别人类里的一个字段。
回复

使用道具 举报

     
发表于 2024-12-15 00:29 | 显示全部楼层
raimouse 发表于 2024-12-14 16:29
是的,我做了个UI程序
目前先弹一个文件选择框选择文件
选择完成后把文件路径写进全局变量

fileselector那种控件有些直接包装成一个函数,直接返回str(选中)或者None(取消)
回复

使用道具 举报

     
发表于 2024-12-15 08:49 | 显示全部楼层
RTLordCaptain 发表于 2024-12-15 00:29
fileselector那种控件有些直接包装成一个函数,直接返回str(选中)或者None(取消) ...

我用的flet框架
本来就是包装成函数返回str或者None了啊
但是后续操作我是其他按钮事件触发的不是返回str后立即触发的
所以需要用一个变量先缓存这个str
事件触发了再读取
回复

使用道具 举报

     
发表于 2024-12-15 08:51 | 显示全部楼层
Sunyalche 发表于 2024-12-14 23:35
说实话除非是有深入继续学习的想法,不然就直接全局变量也没什么问题

平时写写脚本或玩具怎么舒服怎么来 ...

也不算深入吧,毕竟其实我只是网管仔
不是正经开发
只不过想着既然都写了
正规化一点也没坏处
回复

使用道具 举报

     
发表于 2024-12-15 13:32 | 显示全部楼层
raimouse 发表于 2024-12-15 08:49
我用的flet框架
本来就是包装成函数返回str或者None了啊
但是后续操作我是其他按钮事件触发的不是返回str ...

或许可以把显示对话框的逻辑和结果打包在一起
  1. class SelectedFilePath:
  2.   def __init__(self):
  3.     self._path = None
  4.   def showDialog(self):
  5.     self._path = # get from dialog
  6.   def path(self):
  7.     return self._path
复制代码

这样。当然这个类本身算也是一种全局变量吧,但至少按约定不能随便写了(当然python没有真正的私有成员)
回复

使用道具 举报

     
发表于 2024-12-15 14:51 | 显示全部楼层
这跟工地其实是一个道理

你自己在家diy手工,你随便怎么摆各种工具都行,只要不把烙铁顶头上
但如果是个几人作坊,几十几百人小厂,千人大厂,上万人施工的工地
那么拉个屎也需要有严格的流程,否则就是你在b站看到的各种事故集锦

写代码也是同理,你自己一个人开发的项目,不开源也不会有第二个人维护,你爱怎么写都行,只要你自己还记得自己写了啥
几十几百人合作的项目,没人有那个心智和能力正确记忆所有细节,所以需要风险控制的方法,OOP只是行之有效的一种方法,
setter getter 就跟工地施工要开作业票一样,万一出问题了,你在里面加个日志,就能方便溯源


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|上海互联网违法和不良信息举报中心|网上有害信息举报专区|962110 反电信诈骗|举报电话 021-62035905|Stage1st ( 沪ICP备13020230号-1|沪公网安备 31010702007642号 )

GMT+8, 2025-1-22 16:12 , Processed in 0.190949 second(s), 5 queries , Gzip On, Redis On.

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表