Slipping a Fake
Slipping A Fake, Dependency Injection and Inversion Of Control
If you're interested in patterns, here is a big-picture view of the slipping of fakes.Slipping in a fake (SF) is a specialized instance of a larger concept called dependency injection (DI), which is in turn a specialized application
of an even larger concept called inversion of control (IOC).
IOC is a kind of meta-pattern. In its technical sense, it means exactly what it says:
Instead of some class A controlling some class B,
we invert the relationship, and make class B control class A.
The classic example of IOC is the transition from an old-fashioned console I/O program to a windowed program.we invert the relationship, and make class B control class A.
Classic | Windowed |
---|---|
The Application class prompts the user for gestures one at a time, controlling the order in which information is entered to the system. | The Application creates GUI widgets. The widgets are then placed in control: The user can issue any gesture any time they want, and the application responds. |
A class Client needs a service that some Provider offers. (Martin Fowler has commented that it's not 'Dependencies' being injected, it's 'Providers'.)
At first blush, this may not seem like a special case of IOC, but it is.
Classic | Injected |
---|---|
provider = new CustomProvider(); | provider = Provider::getProvider(); |
Client
no longer controls which implementation of Provider
it has.
Instead of having the Client control instantiating the Provider, we have the Client ask the Provider class for an implementation.(Note: There are lots of ways to do this.
This example uses a simple static
method on the Provider
class.)
Slipping a fake is not different from dependency injection in its implementations. Slipping a fake is dependency injection. But slipping
a fake is different in its intention, and thus we use the different name.Dependency injection is a technique we can use for many different purposes.
Slipping a fake is a technique we use for only one purpose: enabling a test.
In this example, we've chosen not to use a
static method in the Provider, but to use an overridable method in the Client instead. Why? So we can use Extract & Override to make our local
Classic | Injected |
---|---|
provider = new CustomProvider(); | provider = this->getProvider(); |
getProvider()
return a useful fake.Read more about this technique in the next page.
If you want to learn more about dependency injection in its wider context, we recommend these two papers:
- Martin Fowler on "IOC containers and Dependency Injection"
- James Shore on "Dependency Injection Demystified"
(Reading...)
Formatting Hints:
To format... | use this markup: |
---|---|
source code | {source:lang=java|lineNumbers=false}...{source} (Supported languages: java, cpp, csharp, c, python.) |
bold text | __some text__ |
italicized text | ~~some text~~ |
underlined text | @@some text@@ |
a method or class name | ``myMethod(...)`` |