A detailed example of IOC and DI in PHP

Source: Internet
Author: User
Recently in the use of the THINKPHP5 framework, looked at his source code, found that there are many places also used to rely on injection (control inversion), feel the need to talk with you about what is dependency injection and how to use it.

Let's look at an example:

<?phpclass a{public $b;p ublic $c;p ublic 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 () {//todoecho ' B ';}} Class C{public function C () {//todo}public function Method () {//todoecho ' C ';}} $a =new A (); $a->method ();? >

The above code, we can easily understand a sentence:

Class A relies on Class B and Class C

That is, if in the future development process, to the Class B or Class C modification, once the change of function, the number of function parameters, and even the entire class structure adjustment, we also have to make corresponding adjustments to a class, a class of independence lost, which is very inconvenient in the development process, that is, we say "holding a full body", If two classes are written by two people, the contradiction often arises at this time ...

In case you really want to change Class B and Class C, there is no way, can not change or try to change the code of Class A? The control reversal is used here.

High-level modules should not be dependent on the underlying module, two should be dependent on abstraction.

Inversion of Control (IOC) is the idea that dependency injection (DI) is the way to implement this thought.

The first method is called: Constructor injection (this method is not recommended, but better than not)

Class A{public $b;p ublic $c;p ublic function A ($b, $c) {$this->b= $b; $this->c= $c;} Public Function Method () {$this->b->method (); $this->c->method ();}}

The client class writes this:

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

A class of constructors rely on Class B and Class C, passed through the constructor parameters, at least one point, that is, Class B object B and Class C object C is created to move to Class A, so once Class B and Class C changes, Class A does not have to be modified, as long as the client class to change it.

If one day, we need to expand Class B, do two Class B subclasses

Class B{public function B () {//todo}public function Method () {//todoecho ' B ';}} Class B1 extends B{public function B1 () {//todo}public function Method () {echo ' B1 ';}} Class B2 extends B{public function B2 () {//todo}public function Method () {echo ' B2 ';}}

Also very simple, the client class writes this:

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

So a class is not concerned about the class B exactly what kind of sub-class, as long as in the client class care on it can be.

The second method is called: Factory mode Injection (recommended)

Class Factory{public function Factory () {//todo}public function Create ($s) {switch ($s) {case ' B ': {return new B (); Case ' C ': {return new C (); Default:{return null;break;}}}

Our Class A code should read:

Class A{public $b;p ublic $c;p ublic function A () {//todo}public function Method () {$f =new Factory (); $this->b= $f Create (' B '); $this->c= $f->create (' C '); $this->b->method (); $this->c->method ();//todo}}

In fact, a small part has been decoupled, at least if the Class B and Class C constructors change, such as modifying function parameters, we only need to change the factory class.

Abstractions should not be dependent on detail, and detail should be dependent on abstraction.

Abstract the methods in class B and Class C to make an interface

Interface Imethod{public function Method ();}

Thus, the $b variable and the $c variable in Class A are no longer a concrete variable, but rather an abstract type of variable, not to run that moment, do not know how their method is implemented.

Class B implements Imethod{public function B () {//todo}public function Method () {//todoecho ' B ';}} Class C implements Imethod{public function C () {//todo}public function Method () {//todoecho ' C ';}}

Summarize several points:

1. We move the creation of Class B objects and Class C objects from Class A to outside Class A

2. Originally class A Relies on Class B and Class C, and now becomes a dependent factory,factory B and C.

Related recommendations:

Example code for PHP control inversion (IOC) and Dependency injection (DI)

Sample tutorials for sharing PHP Dependency Injection (DI) and inversion of control (IoC)

PHP Dependency Injection (DI) and inversion of Control (IoC) Examples Tutorial

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.