Luckmoshy
By Luckmoshy · Published:
Last updated: · No comments
  • ARTICLE: PHP LESSON

  • PHP Dependency Injection


    Over the past few years, dependency injection has been a frequently discussed topic among many corporate developers. Many were concerned that they might spend too much time creating their application architecture without actually accomplishing anything. In this article, I'll outline the benefits of dependency injection for PHP developers creating large, scalable projects.

    Dependency Injection:

    What is it? Let's define dependency injection precisely before we delve further into the topic. Imagine that you are currently employed by a website that features "Question and Answers,". Most likely, you would design a class called Question that includes a member of type Author. In the past, programmers would directly create the Author object in the Question constructor, as in the following example:

    class Author {
        private $firstName;
        private $lastName;
        public function __construct($firstName, $lastName) {
            $this->firstName = $firstName;
            $this->lastName = $lastName;
        }
        public function getFirstName() {
            return $this->firstName;
        }
        public function getLastName() {
            return $this->lastName;
        }
    }
    class Question {
        private $author;
        private $question;
        public function __construct($question, $authorFirstName, $authorLastName) {
            $this->author = new Author($authorFirstName, $authorLastName);
            $this->question = $question;
        }
        public function getAuthor() {
            return $this->author;
        }
        public function getQuestion() {
            return $this->question;
        }
    }

    Despite the fact that many programmers would consider this to be good code, it has a number of issues: 

    • The information provided by the author to the Question constructor has no bearing on the scope of the Question. Since it has nothing to do with the question itself, the author's name belongs inside the Author class. 
    • The Question class and the Author class are closely related. A tedious and time-consuming process, especially in complex applications, results from changing every class where an Author object is created if we add a new parameter to the Author constructor. 
    • The unintended consequence of unit testing the Question class is that the Author class must also undergo testing.
    By injecting dependencies through the constructor of the dependent class, dependency injection ("Constructor Injection") resolves these problems. Code that is extremely maintainable as a result might resemble this:

    class Author {
        private $firstName;
        private $lastName;
        
        public function __construct($firstName, $lastName) {
            $this->firstName = $firstName;
            $this->lastName = $lastName;
        }
        public function getFirstName() {
            return $this->firstName;
        }
        public function getLastName() {
            return $this->lastName;
        }
    }
    class Question {
        private $author;
        private $question;
        public function __construct($question, Author $author) {
            $this->author = $author;
            $this->question = $question;
        }
        public function getAuthor() {
            return $this->author;
        }
        public function getQuestion() {
            return $this->question;
        }
    }

    illogical startup code

    As the project expands, you end up with many levels of objects that must be created when your application starts, so you start passing your dependencies in your class constructors. Depending on the size of your application, creating every object needed to launch it can take a long time and negatively affect performance (as well as produce messy code). Here's an illustration:

    /* 
    Please be aware that this situation doesn't depend on the application's nature.. I only wanted to show how hard-to-maintain/awful such code can be: 
    */
    $filePath = "/path/to/file";
    $fileBuilderFactory = new ConcreteFileBuilderFactory();
    $filesXmlBuilderFactory = new ConcreteFilesXmlBuilderFactory($fileBuilderFactory);
    $softwaresRetrieverCriteriaBuilderFactory = new ConcreteSoftwaresRetrieverCriteriaBuilderFactory($filesXmlBuilderFactory);
    $softwareRetrieverCriteriaBuilderFactory = new ConcreteSoftwaresSoftwareRetrieverCriteriaBuilderFactory($filesXmlBuilderFactory);
    $filesJsonBuilderFactory = new ConcreteFilesJsonBuilderFactory($fileBuilderFactory);
    $objectBuildderFactory = new ConcreteSoftwaresSoftwareObjectBuilderFactory();
    $softwaresSoftwareBuilderFactory = new ConcreteSoftwaresSoftwareBuilderFactory($objectBuildderFactory);
    $xmlSoftwareRepository = new XmlSoftwareRepository($softwaresSoftwareBuilderFactory);
    $softwaresBuilderFactory = new ConcreteSoftwaresBuilderFactory($xmlSoftwareRepository, $softwareRetrieverCriteriaBuilderFactory, $filesJsonBuilderFactory);
    $xmlSoftwaresRepository = new XmlSoftwaresRepository($softwaresBuilderFactory);
    $softwareToHashMap = new ConcreteSoftwareToHashMap();
    $softwaresToHashMap = new ConcreteSoftwaresToHashMap($softwareToHashMap);
    $jsonSoftwaresService = new JsonSoftwaresService($softwaresToHashMap);
    $di = new DependencyInjection($softwaresRetrieverCriteriaBuilderFactory, $xmlSoftwaresRepository, $jsonSoftwaresService);
    This startup code is not particularly long. Your startup code could get much heavier than this if you create a big application. 

    Naturally, this leads to some difficult-to-maintain code. We require a dependency injection program that can read an XML file and generate all the objects required to start the program in order to solve this issue. The objects would then be written to a file and serialized.

     The startup code would then just read that file and make the objects on the fly. Your start-up code is now as straightforward as:

    $objectFilePath = "/path/to/serialized/object/file";
    $di = unserialize(file_get_contents($objectFilePath));

    Use Dependency Injection When

    The best use of dependency injection is when working on long-term projects.
    Dependency injection, in my opinion, is most helpful when used on long-term projects, or those that are actively developed and maintained over an extended period of time. 

    This significantly lowers your expenses and draws in the top developers. But as I already said, I'd advise getting right into the code if you need a demo application to secure a contract or some funding. 

    However, if you go down that road, be aware that the demo will have to be destroyed once you receive a contract and/or funding.

    Comments



    What to Learn

    In business and tips are here

    UFllRXRaZDJpLytvYUpFSzZoL1c3NWRTbkltV2VJeEgwMUo1Y3ZvNEU0bz01