服务定位器 · Decoupling Patterns · 游戏设计模式
解耦模式
组件模式将一个实体拆成多个,解耦不同的领域。 事件序列解耦了两个互相通信的事物,稳定而且及时。 服务定位器让代码使用服务而无需绑定到提供服务的代码。
- 组件模式
- 本质上是功能的模块化,延伸了面向对象的解耦思想
- U3D的编程思想就是面向组件的,MonoBehaviour的子类都可作为组件挂在GameObject上
- 事件序列
- 就像银行办事需要排号一样——每个顾客要处理的事都是一个事件,编号后就形成了天然的事件序列,银行会按一定规则来依次处理队列中的事件
- 一般在底层实现,但宏观上依然存在,例如RTS游戏中通过Shift对一些单位下达前往不同位置的命令
- Unity中协程可以用来做消息队列,防止同帧产生大量的计算
- 服务定位器
- 类似单例模式,在运行时寻找组件(而不是运行前赋值)
- Unity中GetComponent,FindObjectOfType,Find等方法都可帮助实现相关服务的查找,但此类反射方法要避免在运行时高频循环调用
- 拓展——还可以建立一个运行前赋值的服务注册中心(当然也可运行中赋值),其他需要服务的对象在运行时去注册中心查找相关服务,这样做一方面可以避免全局反射的恶果,一方面可以保留服务定位器带来的解耦优势——单例模式也可使用这样的方法来替换(对象注册中心)
组件模式
允许单一的实体跨越多个领域而不会导致这些领域彼此耦合
在今日软件设计的趋势是尽可能使用组件代替继承。 不是让两个类继承同一类来分享代码,而是让它们拥有同一个类的实例。
模式
单一实体跨越了多个领域。为了保持领域之间相互分离,将每部分代码放入各自的组件类中。 实体被简化为组件的容器。
何时使用
组件通常在定义游戏实体的核心部分中使用,但它们在其他地方也有用。 这个模式应用在在如下情况中:
-
有一个涉及了多个领域的类,而你想保持这些领域互相隔离。
-
一个类正在变大而且越来越难以使用。
-
想要能定义一系列分享不同能力的类,但是使用继承无法让你精确选取要重用的部分。
事件队列
解耦发出消息或事件的时间和处理它的时间
模式
事件队列在队列中按先入先出的顺序存储一系列通知或请求。 发送通知时,将请求放入队列并返回。 处理请求的系统之后稍晚从队列中获取请求并处理。 这解耦了发送者和接收者,既静态又及时。
服务定位器
提供服务的全局接入点,避免使用者和实现服务的具体类耦合
模式
服务 类定义了一堆操作的抽象接口。 具体的服务提供者实现这个接口。 分离的服务定位器提供了通过查询获取服务的方法,同时隐藏了服务提供者的具体细节和定位它的过程。
服务器模式将依赖--在两块代码之间的一点耦合--推迟到运行时再连接,这有了更大的灵活度,能以更小的运行时开销,换取很大的灵活性
(如果用的不好会带来单例模式所有的缺点和更多的运行时开销)
记住
服务必须真的可定位
服务不知道谁在定位它
由于定位器是全局可访问的,任何游戏中的代码都可以请求服务,这就意味着服务必须在任何环境下正确工作
服务定位器 · Decoupling Patterns · 游戏设计模式 (tkchu.me)
时序耦合
两块分离的代码必须以正确的顺序调用才能让程序正确运行