一、意图
允许单一实体跨越多个领域而不会导致这些领域彼此耦合。
二、动机
当一个系统涉及到渲染,物理,声音,控制器输入等等...如果都写在一个类中,这个类就显得巨大且不易维护添加,高度耦合。
在使用并发的现代游戏中,为了让代码在多个线程上运行是至关重要的。将游戏分割为多线程的一种通用方法就是通过领域划分。在一个核上运行AI代码,在另一个上播放声音,在第三个上渲染等。
最简单的优化:将每个领域单独写成类。这些类被称为组件类。系统可以有多个组件类,但是他们之间互不知道彼此的存在。
在如今的软件设计趋势是:尽可能使用组件代替继承。不是让两个类继承同一类来分享代码,而是让它们拥有同一个类的实例。
三、组件模式详解
1.适用场景
1.需要分离一个涉及多个领域类的各个领域。
2.一个类很庞大且难以使用
3.想要定义一系列分享不同能力的类,但是使用继承无法让你精确选取要重用的部分。
组件模式通常可以增进性能和缓存一致性。 组件让使用数据局部性模式的CPU更容易组织数据。
2.代码示例
比如Bjorn类。在没有使用组件模式的时候,需要在Updata函数中实现所有领域的更新。
使用组件模式后:
在各个领域的类中实现updata的逻辑:
Bjorn类就变成了一个组件的集合,只需要自己去调用这几个类的updata函数就可以了。
这里还有的优化是使用指针来代替内联的实例。比如输入系统的实例换成输入系统的指针,就可以在演示系统的时候接入一个电脑演示的输入类。
3.对象如何获取组件
1.对象创建组件
i.保证对象总是可以拿到需要的组件
ii.重新设置对象比较困难
2.外部代码提供组件
i.对象更加灵活
ii.对象可以与具体的组件类型解耦。
4.组件之间如何通信
1.通过修改容器对象的状态
i.保持了组件的解耦
ii.需要将组件分享的任何数据存储在容器类中
(这样会浪费内存,如果将渲染专用的数据放入容器对象中,任何隐形对象都会无益地消耗内存)
iii.让组件的通信基于组件运行的顺序
2.通过他们之间的相互引用
让需要交流的组件相互引用,就可以直接交流,无需通过容器类。
i.简单快捷
ii.两个组件紧绑在一起
3.通过发消息
很复杂,会在容器类中建小小的消息系统,允许组件之间相互发送消息。
它有一个简单的receive()
方法,每个需要接受消息的组件类都要实现它。 这里,我们使用一个int
来定义消息,但更完整的消息实现应该可以附加数据。
然后,向容器类添加发送消息的方法。
注意:这里发送的消息,如果本体也监听了这个消息,本体也会收到。小心造成死循环。
i.同级组件解耦
ii.容器类很简单