Jump to content
  • Advertisement
Sign in to follow this  
PrestoChung

Dependency Inversion/Injection

This topic is 2659 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Looking for ideas on dependence in a game engine.
It would be nice to be able to explicitly plan dependencies before hand. But is this possible? Any resources on this would be appreciated.

What I usually end up with is:

-Game objects are 'managed' by higher level code
-Game objects are composed of lower level components

This seems to result in the higher level code has to know about all the differentiated implementations of the lower-level parts (resulting in switches that need to be changed when adding lower level code).

One explanation I have seen is to provide interfaces between different parts of the code that doesn't rely on the specific implementation. I think this was using C#. In C++, can this be achieved by using a 'base' class as the interface to the derived classes? So far I have avoided using virtual functions but maybe it is too limiting without.

Any thoughts on this are appreciated.

Share this post


Link to post
Share on other sites
Advertisement
If you do DI all the way down, you eventually get to all the way out to a single factory that constructs almost every component of the application. Of course, you can break that factory down into sensible modules if you want, but conceptually, that's what you get.

Though, I'm not sure I understand what you're talking about when you say that you have switches that need to be changed when adding lower level code.

Share this post


Link to post
Share on other sites
DI and interfaces are useful together, but they don't need each other.

In C++, you can get "lightweight" interfaces by using little value wrappers, but they aren't entirely free - they incur developer overhead (lots of boilerplate).

For example:

// Big Dependency Header

class BigDependency
{
public:
void functionA();

void functionB();
};

// ******************************
// Light Dependency A Header

class BigDependency;

class LightDependencyA
{
public:
LightDependencyA(BigDependency *big) : big(big)
{
}

void functionA(); // Implementation: big->functionA();

private:
BigDependency *big;
};

// ******************************
// Light Dependency B Header

class BigDependency;

class LightDependencyB
{
public:
// Allows implicit conversion, if you want
LightDependencyB(BigDependency &big) : big(&big)
{
}

void functionB(); // Implementation: big->functionB();

private:
BigDependency *big;
};

// ******************************
// Elsewhere...

void foo(LightDependencyA a)
{
a.functionA();
}

void bar(LightDependencyB b)
{
b.functionB();
}

void example()
{
BigDependency big;

LightDependencyA a(&big);

foo(a);

bar(big);
}

Share this post


Link to post
Share on other sites

DI and interfaces are useful together, but they don't need each other.

In C++, you can get "lightweight" interfaces by using little value wrappers, but they aren't entirely free - they incur developer overhead (lots of boilerplate).


Fortunately, unlike Java or C#, where everything must be a class, C++ has free function and namespaces, removing the need for most boilerplate. Since DI classes should be transient and stateless by design, their class invariants are mostly enforced by caller.

Factories and all the extra crud is a workaround around language design, it's not needed as such.

The header/implementation separation in C/C++ also makes mocks/stubs possible without resorting to all the usual overhead.

Share this post


Link to post
Share on other sites
Slavik81
A switch example:
Let's say we're dealing with game objects that are a collection of components.
We want to construct a game object by providing a list of component types

Object( std::list<ComponentId> );

The way I would deal with that is to iterate over the list of ComponentId s and initialize each one within a switch.

rip-off
I think this is the direction I'm headed. One could do something similar with static functions as well since this doesn't rely on inheritance (static virtual functions are not possible as far as I know?)?

Antheus
Not sure what mocks/stubs are, is there a good explanation of the subject you could point me to?

Also, are you all using DI to mean both Injection AND Inversion?

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!