Maison >développement back-end >tutoriel php >Explication détaillée des exemples Ioc et Di en php

Explication détaillée des exemples Ioc et Di en php

墨辰丷
墨辰丷original
2018-05-22 16:11:231806parcourir

J'utilise le framework ThinkPHP5 récemment. Après avoir regardé son code source, j'ai découvert que l'injection de dépendances (inversion de contrôle) est également utilisée dans de nombreux endroits. Je pense qu'il est nécessaire de parler brièvement avec vous de ce qu'est l'injection de dépendances. qu'est-ce que c'est et comment l'utiliser.

Regardons d'abord un exemple :

<?php

class A
{
	public $b;
	public $c;
	public function A()
	{
		//TODO
	}
	public function Method()
	{
		$this->b=new B();
		$this->c=new C();
		
		$this->b->Method();
		$this->c->Method();
		
		//TODO
	} 
}

class B
{
	public function B()
	{
		//TODO
	}
	public function Method()
	{
		//TODO
		echo &#39;b&#39;;
	}
}

class C
{
	public function C()
	{
		//TODO
	}
	public function Method()
	{
		//TODO
		echo &#39;c&#39;;
	}
}

$a=new A();
$a->Method();

?>

Nous pouvons facilement comprendre le code ci-dessus en une phrase :

La classe A dépend de la classe B et de la classe C

En d'autres termes, si nous devons modifier la classe B ou la classe C dans le futur processus de développement, une fois qu'il s'agit de renommer la fonction, de changer le nombre de paramètres de fonction, ou même en ajustant l'ensemble de la structure de classe, nous ferons les ajustements correspondants à la classe A. L'indépendance de la classe A est perdue, ce qui est très gênant pendant le processus de développement. C'est ce que nous appelons « une chose affecte tout le corps ». ". Si les deux cours sont écrits séparément par deux personnes, oui, des conflits surviennent souvent à ce moment-là. . .

Si on a vraiment besoin de changer les catégories B et C, y a-t-il un moyen de ne pas changer le code de la catégorie A ou de le changer le moins possible ? L'inversion de contrôle est utilisée ici.

Les modules de haut niveau ne doivent pas dépendre de modules de bas niveau, les deux doivent dépendre d'abstractions.

L'inversion de contrôle (IOC) est une idée, et l'injection de dépendances (DI) est une méthode pour mettre en œuvre cette idée.

La première méthode s'appelle : injection de constructeur (cette méthode n'est pas recommandée, mais c'est mieux que de ne pas l'utiliser)

class A
{
	public $b;
	public $c;
	public function A($b,$c)
	{
		$this->b=$b;
		$this->c=$c;
	}
	public function Method()
	{
		$this->b->Method();
		$this->c->Method();
	} 
}

La classe client s'écrit ainsi :

$a=new A(new B(),new C());
$a->Method();

Le constructeur de la classe A dépend de la classe B et de la classe C. Il est passé via les paramètres du constructeur. Au moins, cela est réalisé. Un point est que la création de l'objet de classe B b et de l'objet de classe C c a été déplacée en dehors de la classe A, donc une fois la classe B et la classe C modifiées, la classe A n'a pas besoin d'être modifiée. modifié, changez-le simplement dans la classe client

Supposons qu'un jour, nous devions étendre la classe B et créer deux sous-classes de la classe B

class B
{
	public function B()
	{
		//TODO
	}
	public function Method()
	{
		//TODO
		echo &#39;b&#39;;
	}
}
class B1 extends B
{
	public function B1()
	{
		//TODO
	}
	public function Method()
	{
		echo &#39;b1&#39;;
	}
}
class B2 extends B
{
	public function B2()
	{
		//TODO
	}
	public function Method()
	{
		echo &#39;b2&#39;;
	}
}

C'est aussi très simple, la classe client est comme ça Écrivez :

$a=new A(new B2(),new C());
$a->Method();

Donc la classe A n'a pas besoin de se soucier des sous-classes de la classe B l'a fait, tant qu'il se préoccupe de la classe client.

La deuxième méthode s'appelle : injection de motif en usine (recommandée)

class Factory
{
	public function Factory()
	{
		//TODO
	}
	public function create($s)
	{
		switch($s)
		{
			case &#39;B&#39;:
			{
				return new B();
				break;
			}
			case &#39;C&#39;:
			{
				return new C();
				break;
			}
			default:
			{
				return null;
				break;
			}
		}
	}
}

Notre code de classe A est modifié en :

class A
{
	public $b;
	public $c;
	public function A()
	{
		//TODO
	}
	public function Method()
	{
		$f=new Factory();
		$this->b=$f->create(&#39;B&#39;);
		$this->c=$f->create(&#39;C&#39;);
		
		$this->b->Method();
		$this->c->Method();
		
		//TODO
	} 
}

En fait, une petite partie a été découplée, du moins si les constructeurs de classe B et de classe C changent, comme en modifiant les paramètres de fonction, etc. ., il suffit de changer la classe Factory.

L'abstraction ne doit pas dépendre des détails, les détails doivent dépendre de l'abstraction.

Résumer les méthodes des classes B et C et créer une interface

interface IMethod
{
	public function Method();
}

De cette façon, $ en classe A La variable b et la variable $c ne sont plus une variable concrète, mais une variable de type abstrait. Jusqu'au moment de l'exécution, je ne sais pas comment leur méthode est implémentée.

class B implements IMethod
{
	public function B()
	{
		//TODO
	}
	public function Method()
	{
		//TODO
		echo &#39;b&#39;;
	}
}

class C implements IMethod
{
	public function C()
	{
		//TODO
	}
	public function Method()
	{
		//TODO
		echo &#39;c&#39;;
	}
}

Pour résumer quelques points :

1 On déplace la création des objets de classe B et des objets de classe C en classe A. à l'extérieur de la classe A

2. À l'origine, la classe A reposait sur la classe B et la classe C, mais maintenant A dépend de Factory, et Factory dépend de B et C.

Recommandations associées :

Explication détaillée du code de l'inversion de contrôle (IOC) et de l'injection de dépendances (DI) PHP

Partagez des tutoriels pratiques sur l'injection de dépendances PHP (DI) et l'inversion de contrôle (IoC)

Injection de dépendances PHP (DI) et inversion de contrôle ( IoC) )Exemple de tutoriel

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn