Jump to content

  • Log In with Google      Sign In   
  • Create Account

Dependency Inversion/Injection


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
4 replies to this topic

#1 PrestoChung   Members   -  Reputation: 184

Like
0Likes
Like

Posted 31 August 2011 - 11:36 PM

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.

Sponsor:

#2 Slavik81   Members   -  Reputation: 360

Like
0Likes
Like

Posted 01 September 2011 - 12:05 AM

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.

#3 rip-off   Moderators   -  Reputation: 8764

Like
0Likes
Like

Posted 01 September 2011 - 05:54 AM

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);
}


#4 Antheus   Members   -  Reputation: 2397

Like
0Likes
Like

Posted 01 September 2011 - 09:36 AM

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.

#5 PrestoChung   Members   -  Reputation: 184

Like
0Likes
Like

Posted 02 September 2011 - 01:37 AM

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?




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS