Inversion PHP du contrôle et injection de dépendances

PHPz
Libérer: 2023-03-06 15:08:01
original
1592 Les gens l'ont consulté

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

?>
Copier après la connexion

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();
	} 
}
Copier après la connexion

Classe client Écrivez comme ceci :


$a=new A(new B(),new C());
$a->Method();
Copier après la connexion

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;;
	}
}
Copier après la connexion

C'est également très simple. La classe client est écrite comme ceci :


$a=new A(new B2(),new C());
$a->Method();
Copier après la connexion

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;
			}
		}
	}
}
Copier après la connexion

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
	} 
}
Copier après la connexion

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();
}
Copier après la connexion

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;;
	}
}
Copier après la connexion

Résumé Plusieurs points :

1. On divise les objets de la classe B et de la classe C en classe A. Déplacer la création en dehors de la classe A

2. À l'origine, la classe A reposait sur la classe B et la classe C, mais maintenant il est devenu que 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!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
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
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal