作者cjcat2266 (CJ Cat)
看板GameDesign
标题Re: [程式] Unity的Singleton Pattern实作-Instance
时间Mon Sep 11 16:39:40 2017
※ 引述《littleshan (我正在想要换什麽)》之铭言:
: 先感谢分享,但这边提出一些不同的看法。
: Singleton 本身并不会降低耦合,实际上它造成很强烈的耦合。
感谢分享,我也想要提出一些意见提供参考
刚踏入业界的时候,我也是非常小心地遵从教科书上的教诲
大部分 "缺点多" 或者 "不建议使用" 的系统设计方式一概不碰
与老鸟们合作一段时间之後,反而有不太一样的见解
我们家的共识是,全域变数用起来心里会有疙瘩,没错
但是当其方便性够值得的时候,还是就安心用下去吧
当然,前提是得保有纪律,不落入教科书提及的众多圈套中
我们在乎的方便性不单只是程式写起来简不简洁
是否在debugger里面的watch window能方便检视也很重要
过去我有几次提出不同重构singleton的方法
同事们往往都一语中的: "Good luck getting that in the watch window."
上篇推文有提到,不用singleton那manager类型的物件怎麽管理?
放在MainGame物件里面? 那单一MainGame物件到头来也是个singleton呀
追朔游戏的最上层,总是会有某种形式的singleton存在
所以说要死都不用singleton又显得有点绑手绑脚
如果硬是要只有MainGame这个类别才准许有singleton
其实对watch window稍微不太友善
首先要在watch window里面输入g_mainGame
然後要嘛要手动展开g_mainGame找到想要检视的manager
要嘛得多存个g_mainGame.m_myManager在watch window
当MainGame规模变大、如此手续重复次数变多,watch window使用效率就下降了
又如果为了抽象性,还把众多manager藏到的更神秘的地方
那在一个随便的break point要去挖资料还得更费工夫
我们的做法是,manager类型的直接用全域变数没关系
像是InputManager, NpcManager, ObjectManager
我们都直接用赤裸裸的全域变数g_inputMgr, g_npcMgr, g_objManager
好处是不管游戏停在哪个break point
我要看NPC的清单,然後检视特定NPC的资料
只要在watch window输入g_npcMgr就好,不用从别的出发点爬过去
+ g_npcMgr
|--+ m_aNpc[kMaxNpcs]
|--+ m_aNpc[0]
| m_name "my NPC"
| m_health 90
|--+ m_aNpc[1]
...
当遇到全域变数相关的问题时
我们的做法是见招拆招,目前没有遇到什麽瓶颈
该重构时就重构吧,过度担心反而开发起来绑手绑脚的
一个游戏的开发方向与路程永远是未知领域
系统架构没有最佳解,想要做出 "最正确" 与 "最完美" 的架构,反而是另外一个陷阱
能够实作出目标游戏机制的架构,就是个可行的架构
老话一句:
"Make games, not game engines."
(除非你是在开发Unity或Unreal XD)
以上是我对singleton的一点看法
P.S. 这不代我认为全域变数可以随便用
该有的纪律还是要有
--
Web
http://AllenChou.net
Twitter
http://twitter.com/TheAllenChou
LinkedIn
http://linkedin.com/in/MingLunChou
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 104.174.112.138
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/GameDesign/M.1505119184.A.B8A.html
※ 编辑: cjcat2266 (104.174.112.138), 09/11/2017 16:48:57
1F:推 b87088: 谢谢,感谢分享 09/11 17:11
2F:推 dreamnook: 推个 难得一系列好文 09/11 18:03
3F:推 johnny94: 设计就是一系列的 trade-off 09/11 18:52
4F:推 joseph33: 推 过度担心反而开发起来绑手绑脚的 09/11 21:38
5F:推 kesamia: 推一个 09/11 22:14
6F:推 feather623: 感谢你的延伸分享! 09/11 23:49
7F:→ y3k: 可以说 任何写法都有它的用处 只是singleton被误用滥用造成的 09/12 17:00
8F:→ y3k: 影响很不容易处理 也可以用其他写法预防 09/12 17:01
9F:推 ycjcsie: 我在弄system相关也是直接用singleton 09/16 15:47
10F:推 Ahtram: 或者:把instance弄成private 然後开一堆method去包装,这 09/17 10:34
11F:→ Ahtram: 是比较保守而且让写类别的人可以掌控状况的方法 09/17 10:34
12F:→ Ahtram: 要写比较多东西就是。其实我也常干当作global变数使用就是 09/17 10:35
13F:推 NightDream08: 输入输出这种「只需要而且也只应该有一组」的情况加 09/23 00:14
14F:→ NightDream08: 上又不太容易有state互相影响的场合用Singleton应该 09/23 00:14
15F:→ NightDream08: 没什麽错吧......? 09/23 00:15
16F:→ cjcat2266: 是啊,我觉得合理就用singleton其实没什麽问题 09/23 01:50
17F:→ cjcat2266: 以後有问题再改就好,反正又不能100%预知未来 09/23 01:51
18F:→ cjcat2266: 不如每次修改就以minimal viable product为目标 09/23 01:52