Skip to content

Commit 9f9a64c

Browse files
authored
Update dependencies.md
1 parent b524117 commit 9f9a64c

File tree

1 file changed

+74
-3
lines changed

1 file changed

+74
-3
lines changed

book/dependencies.md

Lines changed: 74 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,80 @@ it doesn't care how these dependencies are satisfied.
2525

2626
You can't eliminate dependencies altogether but you can make them more flexible.
2727

28-
## Inversion of control
29-
30-
3128
## Dependency injection
3229

30+
There are two ways of re-using things in OOP: inheritance and composition.
31+
32+
Inheritance is simple:
33+
34+
```php
35+
class Cache
36+
{
37+
public function getCachedValue($key)
38+
{
39+
// ..
40+
}
41+
}
42+
43+
class CachedWidget extends Cache
44+
{
45+
public function render()
46+
{
47+
$output = parent::getCachedValue('cachedWidget');
48+
if ($output !== null) {
49+
return $output;
50+
}
51+
// ...
52+
}
53+
}
54+
```
55+
56+
The issue here is that these two are becoming unnecessarily coupled or inter-dependent making them more fragile.
57+
58+
Another way to handle it is composition:
59+
60+
```php
61+
interface CacheInterface
62+
{
63+
public function getCachedValue($key);
64+
}
65+
66+
class Cache implements CacheInterface
67+
{
68+
public function getCachedValue($key)
69+
{
70+
// ..
71+
}
72+
}
73+
74+
class CachedWidget
75+
{
76+
private $cache;
77+
78+
public function __construct(CacheInterface $cache)
79+
{
80+
$this->cache = $cache;
81+
}
82+
83+
public function render()
84+
{
85+
$output = $this->cache('cachedWidget');
86+
if ($output !== null) {
87+
return $output;
88+
}
89+
// ...
90+
}
91+
}
92+
```
93+
94+
In the above we've avoided unnecessary inheritance and used interface to reduce coupling. You can replace cache implementation without changing `CachedWidget` so it's becoming more stable.
95+
96+
The process of getting an instance of `CacheInterface` into `CachedWidget` is called dependency injection. There are multiple ways to do so:
97+
98+
- Constructor. Preferred for mandatory dependencies.
99+
- Setter. OK for optional dependencies.
100+
- Property. Potentially violates encapsulation.
101+
33102
## Dependency container
34103

35104
Injecting basic dependencies is simple and easy. You're choosing a place where you don't care about dependencies, which is usually controller which you aren't going to unit-test ever, create instances of dependencies needed and pass these to dependent classes.
@@ -45,3 +114,5 @@ Additionally, lots of dependencies, such as certain third party API wrapper, are
45114
That's what dependency containers are for.
46115

47116
See [official guide](http://www.yiiframework.com/doc-2.0/guide-concept-di-container.html) for more information about Yii's dependency container.
117+
118+
## Inversion of control

0 commit comments

Comments
 (0)