Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dependency Injection mentioned by C++ Google Mock guide

What do they mean with Dependency Injection (Inversion of Control) in this context (Google Mock):

Let's look at an example. Suppose you are developing a graphics program that relies on a LOGO-like API for drawing. How would you test that it does the right thing? Well, you can run it and compare the screen with a golden screen snapshot, but let's admit it: tests like this are expensive to run and fragile (What if you just upgraded to a shiny new graphics card that has better anti-aliasing? Suddenly you have to update all your golden images.). It would be too painful if all your tests are like this. Fortunately, you learned about Dependency Injection and know the right thing to do: instead of having your application talk to the drawing API directly, wrap the API in an interface (say, Turtle) and code to that interface:

class Turtle {
  ...
  virtual ~Turtle() {}
  virtual void PenUp() = 0;
  virtual void PenDown() = 0;
  virtual void Forward(int distance) = 0;
  virtual void Turn(int degrees) = 0;
  virtual void GoTo(int x, int y) = 0;
  virtual int GetX() const = 0;
  virtual int GetY() const = 0;
};

What does it have to do with DI when adding another layer between application code and drawing API by a class? In many Java example about Dependency Injection, usually an object should not be concretely created inside a class. Rather, it should be created elsewhere to separate the implementation coupling between two objects. For example (source from codeproject):

enter image description here

Solution:

enter image description here

As I searched through the answers about DI on Stackoverflow, usually it is asked in the context of Java. Some example used the Java GUI. Usually the examples is so simple and so obvious that I failed to see its significance, except for having better design with less coupling. However, what I want to learn is the meaning behind it. As defined in wiki, Inversion of Control (IoC) means you invert the flow of control of code. So, how does it apply to the Google case? How the actual flow is inverted compare to procedural style? I thought that code is executed sequentially line by line from top to bottom, not from bottom to top?

like image 657
Amumu Avatar asked Feb 01 '26 22:02

Amumu


1 Answers

Wikipedia has good definitions of these:

  1. http://en.wikipedia.org/wiki/Inversion_of_control
  2. http://en.wikipedia.org/wiki/Dependency_injection

Dependency Injection is just a fancy way of saying that the class interacts with another via an interface (the Graphics API) and that it provides a way of changing what the interface points to (i.e. injecting a dependency on another class).

For Inversion of Control, Wikipedia mentions things like the Factory pattern.

It also mentions setter injection (changing an interface implementation using a setter function), construction injection (setting the interface implementation from the constructor) or interface injection (requesting an interface implementation from another interface) and notes that these are types of Dependency Injection.

This is what is happening here -- the program can change the drawing API of the turtle program (Dependency Injection) using a setter method (Inversion of Control).

This allows you to have a test class like this:

struct DrawingTester : public DrawingInterface
{
    void move_to(long x, long y) { printf("moveto %d %d\n", x, y); }
    void line_to(long x, long y) { printf("lineto %d %d\n", x, y); }
};

and drive it through a test program:

int main(int argc, char **argv) {
    DrawingTester drawing;
    Turtle t;
    t.setDrawingApi(&drawing);
    t.runProgramFromFile(argv[0]);
    return 0;
}

You can then have the turtle/logo test programs with expected output from the DrawingTester. For example:

# test1.logo

MOVE 5, 7

# test1.calls

moveto 5 7

and drive this through a test suite (e.g. https://github.com/rhdunn/cainteoir-engine/blob/master/tests/harness.py and https://github.com/rhdunn/cainteoir-engine/blob/master/tests/metadata.py).

like image 179
reece Avatar answered Feb 04 '26 11:02

reece



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!