In terms of game engine modeling, please give your pros and cons for two types of interfacing:
class MySceneObject_Model1 : public IRenderable, public IScriptable, public IAnimatable { ... }
class MySceneObject_Model2
{
protected:
IRenderable* m_ptrRenderable;
IScriptable* m_ptrScriptable;
IAnimatable* m_ptrAnimatable;
public:
IRenderable* GetRenderable();
IScriptalbe* GetScriptalbe();
IAnimatable* GetAnimatable();
}
What if MyObjects have different variations of supported interfaces? For example one of them can be only Scriptable. Some of interfaces could appear in future. Some of them could be very similar to each other: IAnimatableByMorphing, IAnimatableByBones, etc. Some of them can be very close to each other: IRenderable depends on new object's state after IAnimatable's work. I know it is very basic and very wide question, but tell about your experience!
Answer
It is generally preferable to prefer composition to inheritance. There are many available resources on the subject if you ask Google about it. According to that principle, your second example is better. If you take the first approach you will have to implement IAnimatable (or whatever) in every concrete game object class, and you may not be able to easily re-use that code unless you take an approach that is far more like the second option anyhow. This will, in turn, imply you have many different game-object level classes that exist only to mix-and-match different interface implementations. You could achieve this more easily, more cleanly, and with less code using the second approach and simply configuring an object with the appropriate interface implementation objects.
Your second example is actually a very primitive component-based architecture, one where the available component set is rigid. What Edward83 was suggesting in the comments is probably the (currently very trendy) evolution of that architecture where objects are composed of a dynamic list of components.
In the second example, if an object does not supporting animation or scripting, the respective components would be null or you would install a dummy component that implements the interface but does so with no-op methods.
As a note, you probably should not have "IAnimatableByMorphing" or "IAnimatableByBones" interfaces (as implies by the 'I' prefix), rather those should be concrete classes that implement IAnimatable.
No comments:
Post a Comment