求助:面向对象 与 面向过程 及全局变量
C++环境,编写一个打怪物的游戏,分为 主角 和 怪物。这其中肯定涉及到主角和怪物的一系列数据:精灵图片的高宽、位置、速度、生命值、……
如果采用(面向过程)全局变量方式,则这些数据可以直接使用。程序清单也简洁漂亮。
而推荐的面向对象方式,需要设置两个类:主角类CLASS、怪物类CLASS
类内各自的数据成员(高宽、位置、速度)都是private的。还必须添加很多的SetPosition(int X, int Y) 、getPosition()……成员函数,程序长度增加很多,代码显得繁琐、凌乱。在类外使用一个变量,必须调用一次函数,才能得到想要的值。为什么推荐这种脱裤子放屁的方法?
若是开发操作系统、PhotoShop这些大型软件,倒还可以理解。
都是工具,看你需求你自己决定。当然后期加需求的时候别再来发一贴哭诉 超过100种怪物时,你就知道面向对象的好了 本帖最后由 overflowal 于 2024-12-13 14:59 编辑
不要太在意OOP的编程范式,现在新的语言都不乐意玩这套是有原因的。
继承,多态这一套听起来非常美好,但是实际上一上手就可能让你代码整个僵住。
(当然也不是让你完全不抽象,就面条代码写到底
感觉光面向对象也没啥用,得学点设计模式
—— 来自 鹅球 v3.3.92 set_variable和get_variable使用的目的是为了保证变量类型的invariant,变化中保持一些东西不变,以及一些is_valid的保证。
当不需要这些不变形和有效性的验证时,给予变量字段field的访问权。
如果你发现你的包装产生了非高效简洁的代码,那么这个包装不适宜场景。具体的是你的类型编写的问题,或者是范氏本身的问题,就需要仔细考量了。 你整个游戏只有一个角色和一个怪物吗,还是你每个怪物都建一个类 你详细分析了需求和架构后如果仍然觉得没必要oop,那就是没必要
要么是你的能力,要么是你的程序还没有到应该oop的程度
当你开始后悔并考虑重构时,那才是oop ready的时候 本帖最后由 BRRM 于 2024-12-13 17:55 编辑
还必须添加很多的SetPosition(int X, int Y) 、getPosition()……成员函数,程序长度增加很多,代码显得繁琐、凌乱。在类外使用一个变量,必须调用一次函数,才能得到想要的值。为什么推荐这种脱裤子放屁的方法?
防止你乱改,如果你可以随意的赋值,那你就没办法在赋值的过程中进行错误检查。万一你写成 player.x="123",那不是出bug了吗?
(当然,有的语言像 python 可以在语言层面上解决这个问题,直接进行优雅的读取、修改,但是底层仍然是有一个函数进行错误检查。)
不过我觉得你这个问题跟面向对象其实没啥关系。
“面向对象”或者“面向过程”都是一种思维方式,也是一种看待问题的角度。对于计算机来说,不存在所谓的面向对象还是面向过程。
为什么面向对象流行,单纯是面向对象的编码方式对于大多数人来说更方便、更容易让人理解,仅此而已。
说得好 但是我的项目有二十万个对象 分成四十大类 六百个小类 同时有20个人写代码 业务逻辑天天变
每天参数不一样 需要根据基础架构持续扩展以及重写
一是规模大了面向过程无法维护,二是很重要的一点,这种设计方便团队合作,只需要几个厉害的人抽象好框架,然后找一堆菜逼填工作量就行 没错,我推荐你立即使用C
顺便,用C出现问题九成九是你自己哪里没写对,请仔细排查,少发帖问
—— 来自 鹅球 v3.1.88.3 本帖最后由 henvelleng 于 2024-12-13 21:02 编辑
一般批判面向对象的点是继承,你这又是哪一出啊?
c语言也是用结构体封装对象的,把函数指针成员塞进对象里调用,也有构造函数和析构函数的等价版本,这你也不知道吗?
—— 来自 鹅球 v3.1.88.3 看了眼楼主的回复感觉还在上学没有工作。
上学做的那些东西太简单了,无非低成本体验下罢了,要说没必要那确实没必要。 只要你做的东西足够简单,那么面向过程写到底肯定能做,反正面对的也就那么几个东西。
但是东西一多起来……不抽象出来做你就哭吧。 和项目复杂度相关,如果有效代码过万行的话,总是会自己开始封装的。你的游戏如果行数不多的话确实可以不做封装
—— 来自 鹅球 v3.1.90 17年的号问这个问题感觉有点怪,说真的超过一万行代码的项目,你不用面向对象都会很痛苦。说到底面向对象是为了程序的可维护性和可复用性。不然复杂度高起来,面向过程编程你是玩不来的。
还有一般做游戏的话,需要掌握几个常见设计模式:比如工厂模式、单例模式、观察者模式、原型模式等等。你现在还是先找个项目变抄边做最合适。 写游戏直接ecs吧,还面个啥对象 问一下LZ写过多久的代码,有没有和别人一起写代码的经验。
这种问题在我看来应该是非常自然的,你写多了代码自然会理解这些工程实践的优缺点。 lz应该是想做游戏所以自学的编程吧 所有设计模式都可以说只是工程上的最佳实践方案
当你的程序还没能算是工程的时候,确实是没必要管的
如果是做游戏的话,就直接别管这些先撸,先看到结果才有继续的动力和方向 本帖最后由 raimouse 于 2024-12-14 12:16 编辑
借楼问一句
我自己写个python玩具,其实也就几百行的水平很简单
函数之间交换信息用了全局变量但是总感觉不是很好的处理方案
但是函数不是固定顺序执行,也不好直接用返回值啥的来传递信息
还有啥简单方便的方案么 raimouse 发表于 2024-12-14 12:14
借楼问一句
我自己写个python玩具,其实也就几百行的水平很简单
函数之间交换信息用了全局变量但是总感觉不 ...
数据多就封装一个缓冲池,当然其实也是全局,封装了可以加上存取接口控制读写。
程序规模小没必要,就全局变量也行
—— 来自 HUAWEI OCE-AN50, Android 12上的 S1Next-鹅版 v2.5.4 raimouse 发表于 2024-12-14 12:14
借楼问一句
我自己写个python玩具,其实也就几百行的水平很简单
函数之间交换信息用了全局变量但是总感觉不 ...
一般上一个简单的 class 呗
class App:
def __init__(self):
self.var0 = None
self.var1 = None
def action0(self):
self.var0 = "Hello My App"
def action1(self):
self.var1 = self.var0 + ", bye."
def show(self):
print(self.var1)
if __name__ == "__main__":
app = App()
app.action0()
app.action1()
app.show()
全局变量的坏处是你不知道什么时候 那个地方改了. 特别是多人协作的情况下.
软件工程化是特别复杂的东西. 没有一个设计模式是通杀的. 无论是游戏还是工控,状态机都是很好用的东西。全局变量即使不谈软件工程和可读性可扩展性,在并发、可重入等问题上也是噩梦
—— 来自 鹅球 v3.1.88.3 raimouse 发表于 2024-12-14 12:14
借楼问一句
我自己写个python玩具,其实也就几百行的水平很简单
函数之间交换信息用了全局变量但是总感觉不 ...
没有好办法,要么把函数做得更内聚,不依赖外部数据,要么提前规划好有哪些全局状态
—— 来自 鹅球 v3.0.86-alpha raimouse 发表于 2024-12-14 12:14
借楼问一句
我自己写个python玩具,其实也就几百行的水平很简单
函数之间交换信息用了全局变量但是总感觉不 ...
你就自己写个小程序玩那用很多全局变量当然不是不行,只要你自己还记得处理逻辑不会乱掉就行
但要是大型工程或者多人协作,你有一大堆全局变量那玩意发现值不对都不知道是那里改的
再比如大型工程那要保证质量就得搞单元测试,不然随便改点什么就得重新手动测那能把人逼疯了。但是如果你程序里一堆全局变量那单元测试就很难写了
很多东西比如单元测试、LOG、Accessor之类的对写着玩的小程序来说可能累赘或者多余,但是稍大一点的工程不能没有,不然根本没法debug
像全局变量如果必须用的话会包装成singleton,也是为了方便测试,还有限制调用者修改什么的
话说回来只有几百行又不是固定顺序执行是怎么回事,很小的UI程序或者多线程吗 RTLordCaptain 发表于 2024-12-14 15:01
你就自己写个小程序玩那用很多全局变量当然不是不行,只要你自己还记得处理逻辑不会乱掉就行
但要是大型 ...
是的,我做了个UI程序
目前先弹一个文件选择框选择文件
选择完成后把文件路径写进全局变量
后续选确定执行就调用新函数,从全局变量读路径进行操作
选取消就重置全局变量,也不会执行新函数
所以函数执行顺序不是固定的
首先,面向对象是在你整个业务确定不会有改动的情况下去写的,等你发现要对整个功能有频繁改动的时候你就会觉得很麻烦,比如 ddd 架构,一个简单的对象为了对象而对象,面向过程就好多了,代码虽然冗余且差,但好修改 raimouse 发表于 2024-12-14 12:14
借楼问一句
我自己写个python玩具,其实也就几百行的水平很简单
函数之间交换信息用了全局变量但是总感觉不 ...
协程。函数之间交换信息,意味的是对等调用,而不是主从调用。
—— 来自 鹅球 v3.1.89 本帖最后由 格林达姆 于 2024-12-14 22:16 编辑
raimouse 发表于 2024-12-14 12:14
借楼问一句
我自己写个python玩具,其实也就几百行的水平很简单
函数之间交换信息用了全局变量但是总感觉不 ...
业务和数据分离,所有数据读写都放个独立的工具类里通过接口访问。这样多线程也好去控制 格林达姆 发表于 2024-12-14 22:12
业务和数据分离,所有数据读写都放个独立的工具类里通过接口访问。这样多线程也好去控制 ...
目前看下来好像多数意见都是封装一个专门的缓存类用来控制变量读写
等周一上班了我在研究下
谢谢楼里各位前辈的意见 raimouse 发表于 2024-12-14 23:09
目前看下来好像多数意见都是封装一个专门的缓存类用来控制变量读写
等周一上班了我在研究下
谢谢楼里各位 ...
说实话除非是有深入继续学习的想法,不然就直接全局变量也没什么问题
平时写写脚本或玩具怎么舒服怎么来就行,真正想写正经程序再来搞这些范式。
像工程代码,一个大点的类几百行代码都很正常,可能你的全局变量就相当于别人类里的一个字段。 raimouse 发表于 2024-12-14 16:29
是的,我做了个UI程序
目前先弹一个文件选择框选择文件
选择完成后把文件路径写进全局变量
fileselector那种控件有些直接包装成一个函数,直接返回str(选中)或者None(取消) RTLordCaptain 发表于 2024-12-15 00:29
fileselector那种控件有些直接包装成一个函数,直接返回str(选中)或者None(取消) ...
我用的flet框架
本来就是包装成函数返回str或者None了啊
但是后续操作我是其他按钮事件触发的不是返回str后立即触发的
所以需要用一个变量先缓存这个str
事件触发了再读取 Sunyalche 发表于 2024-12-14 23:35
说实话除非是有深入继续学习的想法,不然就直接全局变量也没什么问题
平时写写脚本或玩具怎么舒服怎么来 ...
也不算深入吧,毕竟其实我只是网管仔
不是正经开发
只不过想着既然都写了
正规化一点也没坏处
raimouse 发表于 2024-12-15 08:49
我用的flet框架
本来就是包装成函数返回str或者None了啊
但是后续操作我是其他按钮事件触发的不是返回str ...
或许可以把显示对话框的逻辑和结果打包在一起
class SelectedFilePath:
def __init__(self):
self._path = None
def showDialog(self):
self._path = # get from dialog
def path(self):
return self._path
这样。当然这个类本身算也是一种全局变量吧,但至少按约定不能随便写了(当然python没有真正的私有成员) 这跟工地其实是一个道理
你自己在家diy手工,你随便怎么摆各种工具都行,只要不把烙铁顶头上
但如果是个几人作坊,几十几百人小厂,千人大厂,上万人施工的工地
那么拉个屎也需要有严格的流程,否则就是你在b站看到的各种事故集锦
写代码也是同理,你自己一个人开发的项目,不开源也不会有第二个人维护,你爱怎么写都行,只要你自己还记得自己写了啥
几十几百人合作的项目,没人有那个心智和能力正确记忆所有细节,所以需要风险控制的方法,OOP只是行之有效的一种方法,
setter getter 就跟工地施工要开作业票一样,万一出问题了,你在里面加个日志,就能方便溯源
页:
[1]
2