Maison  >  Article  >  développement back-end  >  Explication détaillée de l'exemple de code de PHP Inversion of Control (IOC) et Dependency Injection (DI)

Explication détaillée de l'exemple de code de PHP Inversion of Control (IOC) et Dependency Injection (DI)

黄舟
黄舟original
2017-03-13 16:34:061877parcourir

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();

?>

Le code ci-dessus, nous pouvons facilement comprendre une phrase :

Classe A Dépend deClasse B et Classe C

C'est-à-dire que si dans le processus de développement futur, la Classe B ou la Classe C doit être modifiée, une fois la fonction est renommé, Lorsque le nombre de paramètres de fonction change, ou même la structure entière de la classe est ajustée, nous devons apporter 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-à-dire que nous, comme le dit le proverbe, "Une chose affecte tout le corps." Si les deux catégories sont écrites séparément par deux personnes, 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épendance (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();
	} 
}

Classe client Écrivez comme ceci :


$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 transmis via les paramètres du constructeur. est atteint, c'est-à-dire la classe BObjetLa création de l'objet b et C de l'objet 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, 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 également très simple. La classe client est écrite comme ceci :


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

La classe A n'a donc pas besoin de se soucier des sous-classes de la classe B. Elle doit seulement s'en soucier. à propos de la classe client.

La deuxième méthode s'appelle : Modèle d'usineInjection (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 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
	} 
}

a en fait découplé une petite partie, du moins si le constructeur de la classe B et de la classe C change, comme en modifiant les paramètres de la 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();
}

comme celle-ci, le $ bvariable et $c variable dans la classe A ne sont plus une variable concrète, mais une variable de type classe abstraite Jusqu'au moment de l'exécution, on ne sait 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 en dehors 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.

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