Heim  >  Artikel  >  Backend-Entwicklung  >  Beispiel-Tutorial zu PHP Dependency Injection (DI) und Inversion of Control (IoC).

Beispiel-Tutorial zu PHP Dependency Injection (DI) und Inversion of Control (IoC).

零下一度
零下一度Original
2017-06-23 14:25:242384Durchsuche

Um die Konzepte von PHP Dependency Injection und Inversion of Control zu verstehen, müssen Sie die folgenden zwei Probleme verstehen:

  • DI— —Abhängigkeitsinjektion

  • IoC——Kontrollumkehr

Was ist Abhängigkeitsinjektion

Ich kann nicht ohne dich leben , also bist du meine Abhängigkeit. Um es ganz klar auszudrücken:

ist nicht mein eigenes, aber es ist das, was ich brauche und worauf ich mich verlasse. Alles, was extern bereitgestellt werden muss, erfordert eine Abhängigkeitsinjektion.

Beispiel für eine Abhängigkeitsinjektion

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Boy {
  protected $girl;
 
  public function __construct(Girl $girl) {
    $this->girl = $girl;
  }
}
 
class Girl {
  ...
}
 
$boy new Boy();  // Error; Boy must have girlfriend!
 
// 所以,必须要给他一个女朋友才行
$girl new Girl();
 
$boy new Boy($girl); // Right! So Happy!

Aus dem obigen Code können wir ersehen, dass während der Erstellung eine Boystarke AbhängigkeitGirl in eine Instanz von Girl eingefügt werden muss.

Warum gibt es also ein Konzept von 依赖注入? Welches Problem löst 依赖注入?

Ändern wir den obigen Code in den Code, den wir alle als Anfänger geschrieben haben:

1
1
2
3
4
5
6
7
class Boy {
  protected $girl;
 
  public function __construct() {
    $this->girl = new Girl();
  }
}
2
3
4

5
6

7Boy
class Boy {Boy
protected $girl;Boy
public function __construct() {

$this->girl = new code> <code class="php plain">Girl();Boy
}LoliGirl
}GirlLoliGirl
tr>
Was ist der Unterschied zwischen dieser Methode und der vorherigen Methode?
1
2
3
4
5
6
7
8
9
10
11
12
class LoliGirl {
 
}
 
class Boy {
  protected $girl;
 
  public function __construct() {
      //  $this->girl = new Girl();  // sorry...
      $this->girl = new LoliGirl();
  }
}
Wir werden feststellen, dass die Freundin von fest im Körper von verankert ist. . . Jedes Mal, wenn ich eine andere Art von Freundin haben möchte, muss ich mich nackt ausziehen. Eines Tages mag er eine wirklich und möchte unbedingt, dass sie seine Freundin ist. . . was zu tun? Werden Sie wiedergeboren. . . Enthülle dich selbst. . . Wirf weg. . . Stecken Sie hinein. . .
1
2
3
4
5
6
7
8
9
10
11
12
class <code class="php plain">LoliGirl {
}
class Boy {
code><code class="php keyword">protected $girl;
public function __construct() {
// $this->girl = new Girl(); // sorry...
$this->girl = new LoliGirl();
}
}

Eines Tages Boy verliebte ich mich in Schwester Yu....Boy Es ist so nervig. . .

Fühlst du dich schlecht? Jedes Mal, wenn ich jemanden treffe, der mich aufrichtig behandelt, muss ich mich so quälen. . .

Boy sagte: Ich möchte stärker werden. Ich möchte nicht immer wieder verändert werden!

Okay, machen wir Boy etwas stärker:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
interface Girl {
  // Boy need knows that I have some abilities.
}
classLoliGril implement Girl {
  // I will implement Girl's abilities.
}
classVixen implement Girl {
   // Vixen definitely is a girl, do not doubt it.
}
class Boy {
  protected$girl;
  publicfunction__construct(Girl $girl) {
    $this ->girl =  $girl;
  }
}
$loliGirl new LoliGirl();
$vixen
$boy new Boy($vixen);

Boy Ich bin sehr froh, dass ich endlich ein anderes Leben erleben kann, ohne mich öffnen zu müssen. . . So glücklich!

Abhängigkeitsinjektionsmethode

1. Konstruktorinjektion

1
1
2
3
4
5
6
7
8
<?php
class Book {
private $db_conn;
public function __construct($db_conn) {
$this->db_conn = $db_conn;
  }
}
2
3
4
5
6
7
8
<?php<🎜>
class Book {<🎜>
</ code ><code class="php keyword">private $db_conn;<🎜>
<🎜>
< Code class="php keyword">public function __construct( $db_conn) {<🎜>
< Code class="php variable">$this->db_conn = $db_conn;
} code ><div class="line number8 index7 alt1"><code class="php plain">}

2. Setter-Injektion

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?php
class Book {
private $db;
private $file;
function setdb($db) {
$this->db = $db;
    }
    function setfile($file) {
        $this->file = $file;
    }
}
class file {
}
class db {
}
// ...
class test {
    $book new Book();
    $book->setdb(new db());
    $book->setfile(new file());
}

Zusammenfassung:

Da die meisten Anwendungen aus zwei oder mehr Klassen bestehen, die zusammenarbeiten, um Geschäftslogik zu implementieren Erhalten Sie einen Verweis auf das Objekt, mit dem es zusammenarbeitet (d. h. das Objekt, von dem es abhängt). Wenn dieser Erfassungsprozess allein implementiert wird, ist der Code stark gekoppelt und schwer zu warten und zu debuggen.

Deshalb haben wir das Konzept der Abhängigkeitsinjektion entwickelt, das die folgenden Probleme löst:

  • Entkopplung zwischen Abhängigkeiten

  • Unit-Tests, praktisch für Mock

Der Code der beiden oben genannten Methoden ist sehr klar, aber wenn wir viele Abhängigkeiten einfügen müssen, müssen wir viele Zeilen hinzufügen wird verglichen Unüberschaubar.

Eine bessere Lösung besteht darin, eine Klasse als Container für alle Abhängigkeiten zu erstellen. In dieser Klasse können Sie die erforderlichen Abhängigkeiten speichern, erstellen, abrufen und finden. Lassen Sie uns zunächst das Konzept von IOC

Inversion Of Control (IOC) verstehen.

Inversion of Control ist ein Konzept in der objektorientierten Programmierung. Ein Design Prinzip, das verwendet werden kann, um die Kopplung zwischen Computercodes zu reduzieren. Die gebräuchlichste Methode heißt Dependency Injection (Dependency Injection, DI), die andere heißt „Dependency Lookup“. Durch die Umkehrung der Kontrolle übergibt eine externe Entität, die alle Objekte im System steuert, bei der Erstellung eines Objekts die Referenz des Objekts, von dem sie abhängt, an dieses. Man kann auch sagen, dass Abhängigkeiten in das Objekt eingefügt werden.

1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
class Ioc {
protected $db_conn;
public static function make_book() {
$new_book = new Book();
$new_book->set_db(self::$db_conn);
        //...
        //...
        //其他的依赖注入
        return $new_book;
    }
}
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php<🎜>
<🎜>
class Ioc {</code ><🎜><div class="Zeilennummer4 index3 alt1"><code class="php Leerzeichen"> protected $db_conn;<🎜>
<🎜>
< Code class="php leerzeichen"> öffentlich statisch Funktion make_book() {<🎜>
$new_book = new Book();<🎜>
$new_book ->set_db(self::$db_conn);
//... //...
//Andere Abhängigkeitsinjektion
return $new_book;
}
}

Wenn Sie zu diesem Zeitpunkt eine Buchinstanz erhalten möchten, müssen Sie nur $newone = Ioc::makebook(); ausführen.

Das Obige ist eine spezifische Instanz von Container. Um eine bestimmte Abhängigkeitsinjektionsmethode zu schreiben, ist es besser, die Registrierungsregistrierung zu verwenden 🎜>

3
45
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<?php
/**
* 控制反转类
*/
classIoc {
/**
* @var array 注册的依赖数组
*/
protectedstatic$registry= array();
/**
* 添加一个 resolve (匿名函数)到 registry 数组中
* @return void
*/
public static function register($name, Closure $resolve) {
static::$registry[$name] = $resolve;
}
 
/**
* 返回一个实例
*
* @param string $name 依赖的标识
* @return mixed
* @throws Exception
*/
public static function resolve($name) {
if (static::registered($name)) {
$name = static::$registry[$name];
return $name();
}
 
throw new Exception("Nothing registered with that name");
}
 
/**
* 查询某个依赖实例是否存在
*
* @param string $name
* @return bool
*/
public static function registered($name) {
return array_key_exists($name, static::$registry);
}
}

Sie können sich jetzt registrieren und einen

< injizieren div class="Zeilennummer1 index0 alt2">1
1
2
3
4
5
6
7
8
9
10
11
<?php
Ioc::register("book", function () {
$book = new Book();
$book->setdb('db');
    $book->setfile('file');
 
    return $book;
});
 
// 注入依赖
$book = Ioc::resolve('book');
2
3
4
5
6
7
8
9
10 11
<?php<🎜>
Ioc::register("book"<🎜><🎜> () {<🎜>
< 🎜>$book = new Book();<🎜>
<🎜>$book- >setdb('db'
$book->setfile('file'
$book;
});
//Abhängigkeiten einfügen
$book = Ioc::resolve('book' code>

Zusammenfassung der Fragen

1. Wer sind die Teilnehmer?

Antwort: Im Allgemeinen gibt es drei Parteien, eine ist ein Objekt, die andere ist eine externe Ressource eines Objekts. Lassen Sie mich die Substantive noch einmal erklären. Der IoC/DI-Container bezieht sich einfach auf ein Rahmenprogramm, das zur Implementierung der IoC/DI-Funktionen verwendet wird Von außerhalb des Objekts stammende Ressourcen werden kollektiv als Ressourcen bezeichnet, z. B.: andere vom Objekt benötigte Objekte oder vom Objekt benötigte Dateiressourcen usw.

2. Abhängigkeit: Wer ist von wem abhängig? Warum gibt es Abhängigkeiten?

Antwort: Ein Objekt hängt vom IoC/DI-Container ab. Abhängigkeiten sind unvermeidlich. In einem Projekt gibt es verschiedene Beziehungen zwischen verschiedenen Klassen, und es ist unmöglich, dass alle vollständig unabhängig sind, was zu Abhängigkeiten führt. Die traditionelle Entwicklung besteht darin, bei Verwendung anderer Klassen direkt aufzurufen, wodurch eine starke Kopplung entsteht, die vermieden werden sollte. Die Abhängigkeitsinjektion leiht Container aus, um abhängige Objekte zu übertragen und eine Entkopplung zu erreichen.

3. Injektion: Wer spritzt in wen? Was genau wird gespritzt?

Antwort: Injizieren Sie die benötigten externen Ressourcen über den Container in das Objekt

4. Umkehrung der Kontrolle: Wer kontrolliert wen? Was kontrollieren? Warum heißt es Umkehrung?

Antwort: Das Containerkontrollobjekt von IoC/DI steuert hauptsächlich die Erstellung von Objektinstanzen. Die Umkehrung erfolgt relativ zur positiven Richtung. Was gilt also als positive Richtung? Denken Sie über die Anwendung unter normalen Umständen nach, wenn Sie C in A verwenden möchten. Natürlich wird das Objekt von C direkt erstellt, dh die erforderliche externe Ressource C wird aktiv in Klasse A abgerufen. Diese Situation wird als vorwärts bezeichnet. Was ist also umgekehrt? Das heißt, Klasse A erhält C nicht mehr aktiv, sondern wartet passiv darauf, dass der IoC/DI-Container eine Instanz von C erhält, und fügt sie dann umgekehrt in Klasse A ein.

5. Sind Abhängigkeitsinjektion und Umkehrung der Kontrolle dasselbe Konzept?

Antwort: Wie aus dem Obigen hervorgeht: Die Abhängigkeitsinjektion wird aus der Perspektive der Anwendung beschrieben. Die Abhängigkeitsinjektion kann ausführlicher beschrieben werden: Die Anwendung hängt vom zu erstellenden Container ab Injizieren Sie die benötigten externen Ressourcen. Während die Umkehrung der Kontrolle aus der Perspektive des Containers beschrieben wird, ist die Beschreibung vollständig: Der Container steuert die Anwendung, und der Container injiziert umgekehrt die von der Anwendung benötigten externen Ressourcen in die Anwendung.

Das obige ist der detaillierte Inhalt vonBeispiel-Tutorial zu PHP Dependency Injection (DI) und Inversion of Control (IoC).. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn