如何减少实体组件系统中的鸭类现象?
示例
这是一个coliru演示。
在我的ECS中有两个系统:-
System_Projectile:管理所有弹丸和子弹方面。
System_Physic:管理物理的组成部分。
有两个组件类型:Com_Projectile、Physics.。
有时,我发现在某个组件中缓存指向另一个实体的指针是很好的:-
class Com_Projectile : public Component{
public:
Entity* physic;
Entity* physicSecondary; //just to show that it is possible to have >1 physic
};如果我想改变Com_Projectile的位置,我会打电话给manage(Com_Projectile::physic)。
class System_Projectile{
public: static void manage(Entity* projectile){
Com_Projectile* comP = getComponent<Com_Projectile>(projectile);
//suffer duck-typing at "comP->physic"
System_Physic::setVelocity(comP->physic,Vec3(1,0,0));
}
};问题
基于上述代码段的实际程序工作正常。
然而,在编码时,Com_Projectile::physic会遇到鸭式输入.
physic类型的任何physic语义线索。
(变量名称和注释除外)System_Physic::),
然后回忆函数的名称(在本例中为System_Physic::setVelocity())。在我过去的日子里,当我使用大量的(深)继承时,它要容易得多,就像这样:
physic->setVelocity(Vec3(1,0,0));我真的很想念可爱的内容,帮助列出所有与物理相关的功能。

问题
如何减少某些ECS系统中的鸭型?
更具体地说,什么是设计模式,使可爱的内容-协助再次?
我现在的解决办法
让Com_Projectile缓存Physic* physic而不是Entity*:-
class Com_Projectile{
public: Physics* physic; //edited from "Entity* physic"
};Disadvantage:-
Physics内部转发声明Com_Projectile.h。setVelocity())从系统(例如Sys_Physic::)转移到组件(例如Physics::)。发布于 2017-06-10 01:52:33
如何减少某些ECS系统中的鸭型? 更具体地说,什么是设计模式,使可爱的内容-协助再次?
其中一个想法是将组件实现视为与系统交互的管道。不管怎样,这就是他们的意图,是一种数据驱动的方式来影响行为。
class Physics : public Component<Physics> {
public:
Vector3 GetVelocity() const;
void SetVelocity(const Vector3& velocity);
private:
Vector3 velocity_;
}现在,为了设置速度,这是一个简单的调用:
Physics* physics = getComponent<Physics>( projectile->physic );
if ( physics )
physics->SetVelocity( Vector3( 1, 0, 0 ) );然后,物理系统的工作是获取物理分量上的速度,并将其与任何其他数据属性一起应用到内部物理模拟中。
换句话说,将系统的输入状态视为当前组件值和先前系统发出的任何其他可变状态的组合。
除了避免您提到的鸭子类型之外,您还得到了更容易理解的代码,而且代码流也更容易。它还打开了容易被脚本系统和其他外部影响者变异的大门,所有这些都是通过操纵组件上的getter/setter来实现的。
https://stackoverflow.com/questions/44147862
复制相似问题