A discussion on PHP dependency injection and control inversion (II.)

Source: Internet
Author: User

Today, a friend saw Yii2 introduced in the dependency injection confused, before I wrote a similar article sent him to see, may not have a deep understanding of it, here I would like to describe the principle of dependency injection, as far as possible to say easy to understand:
First of all, the concept of the problem (conceptual problem my personal principle is always a simple glance at the concept, through an example to deepen the understanding of the concept)

To understand the two concepts of PHP Dependency Injection and control inversion , we still have to figure out the following two issues:

    • Di--dependency Injection Dependency Injection
    • Ioc--inversion of Control inversion
What is Dependency injection

No job, no money, no money I can not live, then, work and money is my dependence, money I can reluctantly drop a good living, and then plainly is:

Things are not my own, they are all I need. All that needs to be externally provided is the need for dependency injection.

Example of dependency Injection
<?PHPclassWork {protected $money=5000.0;//Base salary Public function__construct (Money$money) {        $this->money =$money; Echo' I need money '; }}classMoney {}$work=NewWork ();//Output discovery
Fatal Error: uncaught typeerror:argument 1 passed to Work::__construct () must is an instance of money, none given, called in D:\web\ test\do.php on line, defined in D:\web\test\do.php:5 Stack trace: #0 D:\web\test\do.php (): Work->__construct () #1 {main} thrown inD:\web\test\do.phpOn line5

From the above code we can see that the work relies heavily on Money an instance that must be injected at construction time Money . We change to the following:

<?PHPclassWork {protected $money=5000.0;//Base salary Public function__construct (Money$money) {        $this->money =$money; Echo' I need money '; }}classMoney {}//$work = new Work ();//So the job has to give him money .$money=NewMoney ();$work=NewWork ($money);//output I need money

So why do we have 依赖注入 this concept, and 依赖注入 what exactly is the problem solved? Let's fix the code that we wrote in our Beginner's code:

<? PHP class work {    protected$money =5000.0;//Base salary: Public function      __construct () {        $thisnew money ();    }}

How is this different from the previous approach? For example, one day I went to Baidu, the basic salary of 6000, we will find every time to Work regenerate money. Like one day Work升职加薪到6k啦 , what? Rebirth yourself ... Throw Away Money ... bring the 6k in ...

<? PHP class Baidumoney {} class Work {    protected$money=5000.0;      Public function __construct () {        //  $this->money = new Money ();        $this New Baidumoney ();    }}

One day ... Work想去BAT . work so annoying ... Doesn't it feel good to change jobs? Every time, not long to wait for the people to torture themselves Work so ... Say, I'm going to be a little stronger. I don't want to be changed! Well, let's make it a Work little stronger:

<?PHPInterfaceMoney {}classBaidumoneyImplementsMoney {}classAlibabaImplementsMoney {}classWork {protected $money=5000.0;  Public function__construct (Money$money) {        $this->money =$money; }}$baidu=NewBaidumoney ();$alibaba=NewAlibaba ();$boy=NewWork ($baidu);$boy=NewWork ($alibaba);

Finally can go to bat experience different life ...

Dependency Injection method

1. Constructor injection

<? PHP class Book {  private$db _conn;      Public function __construct ($db _conn) {    $this$db _conn;  }} 

2. Setter Injection

<?PHPclassBook {Private $db; Private $file; functionSetdb ($db) {        $this->db =$db; }     functionSetfile ($file) {        $this-file=$file; }} class file {} classdb {}classTest {$book=NewBook (); $book->setdb (Newdb ()); $book->setfile (New file());}

Summary:

Because most applications implement business logic by cooperating with each other by two or more classes, each object needs to get a reference to the object it is working with (that is, the object it depends on). If this acquisition process is implemented on its own, it will result in highly coupled code and difficult to maintain and debug.

So there is the concept of dependency injection, which solves the following problems:

    • Decoupling between dependencies
    • Unit test for easy mock

The two methods described above are very clear, but when we need to inject a lot of dependencies, it means we have to add a lot of rows that are more difficult to manage.

The better solution is to create a class as a container of all dependencies, where you can store, create, retrieve, and find the dependencies you need. Let's take a look at the IOC concept (and play with the concept again, don't worry, look at the code to explain all the amount)

Control inversion (inversion of control, IOC)

control inversion is a design principle in object-oriented programming, which can be used to reduce the coupling degree between computer code. The most common of these is called Dependency injection (Dependency injection, DI), and a "dependency lookup" (Dependency lookup). By controlling the inversion, the object is created by an external entity that regulates all objects within the system, passing a reference to the object on which it depends. It can also be said that the dependency is injected into the object.

<?PHPclassIoc {protected $db _conn;  Public Static functionMake_book () {$new _book=NewBook (); $new _book->set_db (self::$db _conn); //...//other Dependency injection        return $new _book; }}

At this point, if you get a book instance, you only need to execute $newone = Ioc::makebook ();

The above is a concrete example of container, it is best not to put a specific dependency injection into the method, the use of registry registration, get get better

<?PHP/** * Control reversal class*/classIoc {/** * @var array of dependent arrays registered*/    protected Static $registry=Array(); /** * Add a resolve (anonymous function) to the registry array * * @param string $name dependent identity * @param Closure $resolve an anonymous function, used to create an instance * @return void*/     Public Static functionRegister$name, Closure$resolve) {        Static::$registry[$name] =$resolve; }     /** * Returns an instance * * @param string $name-dependent identity * @return Mixed * @throws \exception*/     Public Static functionResolve$name) {        if(Static:: Registered ($name)) {            $name=Static::$registry[$name]; return $name(); }         Throw New\Exception("Nothing registered with that name"); }     /** * query whether a dependent instance exists * * @param string $name * @return bool*/     Public Static functionRegistered ($name) {        return array_key_exists($name,Static::$registry); }}

You can now register and inject a

<? PHPIOC function () {    $bookNew book ();     $book->setdb (' db ');     $book->setfile (' file ');      return $book  //  injection dependent $book = ioc::resolve (' book ');
Question Summary 1, who are the participants?

A : There are generally three-party participants, one is an object, one is a Ioc/di container, and the other is an external resource for an object. And the noun to explain, an object refers to an arbitrary, ordinary Java object; The Ioc/di container is simply a framework program used to implement the Ioc/di function, and the object's external resources refer to what the object needs, but it is obtained from outside the object, collectively referred to as resources, such as: other objects required by the object, or the file resources required by the object, etc.

2, dependence: Who depends on who? Why is it dependent?

A : an object is dependent on the Ioc/di container. Dependence is unavoidable, and in a project there are various kinds of relationships between classes, which cannot be completely independent, which forms a dependency. Traditional development is called directly when using other classes, which creates strong coupling, which is to be avoided. The dependency injection borrowing container transfers the dependent object implementation decoupling.

3, injection: Who injected into who? What exactly is injected?

A : inject the external resources needed by the container to the object

4. Control reversal: Who Controls who? Control what? Why is it called inversion?

Answer: The container control object of Ioc/di, which is mainly to control object instance creation. Reversal is relative to the positive, then what is positive? Consider the general application, what would you do if you were to use C in a? Of course, it is directly to create a C object, that is, in class A to take the initiative to obtain the required external resource C, this situation is called forward. So what's the reverse? Is that class A no longer takes the initiative to acquire C, but passively waits, waits for the Ioc/di container to get an instance of C, and then injects the reverse into Class A.

5. Is the same concept of dependency injection and control inversion?

A : as you can see from the above, dependency injection is described from the perspective of the application, which can describe the full point of dependency injection: The application relies on the container to create and inject the external resources it needs, while control inversion is described from the container's perspective, describing the complete point: the container control application, The external resources required by the container to inject the application into the application in reverse.

A discussion on PHP dependency injection and control inversion (II.)

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.