Home > Article > Backend Development > Let's talk about dependency injection, containers and appearance patterns in framework development (Part 1)
This article mainly introduces the dependency injection, container and appearance mode (upper part) about chatting framework development. It has a certain reference value. Now I share it with you. Friends in need can refer to it
1. Dependency injection and decoupling
Men and women in love often say, I can’t live without you. What a deep dependence this is~~
Programming The dependence in work is essentially the same as the dependence in our lives: my work cannot be done without your support. Without you, there would be no me.
There are two types of dependencies: one is functional, and the other is sequential. Let’s use examples to illustrate:
We now have such a task:
User login operations
1. Involves database operations, data verification, and template output;
2. Corresponds to Db class, Validate class, and View class respectively;
3.Only Demonstration and specific examples are required for students to complete by themselves;
Before formal coding, let’s briefly understand what a client is?
1. Client: As long as it can initiate a request, it can be regarded as a client, a browser, or a piece of code.
2. The following code instantiates the User class and calls Its internal logon method works
3. Therefore, $user = new User(); is the client code
4. Or, it can also be understood this way, anything written in a class or function Other than the code, it can be regarded as the client
The source code is as follows:
<?php //数据库操作类 class Db { //数据库连接 public function connect() { return '数据库连接成功<br>'; } } //数据验证类 class Validate { //数据验证 public function check() { return '数据验证成功<br>'; } } //视图图 class View { //内容输出 public function display() { return '用户登录成功'; } } //用户类 class User { //用户登录操作 public function login() { //实例化Db类并调用connect()连接数据库 $db = new Db(); echo $db->connect(); //实例化Validate类并调用check()进行数据验证 $validate = new Validate(); echo $validate->check(); //实例化视图类并调用display()显示运行结果 $view = new View(); echo $view->display(); } } //创建User类 $user = new User(); //调用User对象的login方法进行登录操作 echo $user->login();
Although the above code can work normally, there are still the following problems:
1. Above Of the four classes, only User is the actual work class, and the other three are tool classes (Db, Validate, View)
2. Once the tool classes called in the work class change, these tools must be modified All reference codes of the class, such as Db parameter changes
3. The caller of the work class must be very familiar with all tool classes to be used, and must understand the parameters and return values
4 . The work class has formed a serious dependence on the above three tool classes, which is also called severe coupling between classes.
Now we use the most commonly used dependency injection (DI) to decouple the coupling
We First understand the basic ideas of decoupling:
1. Dependency injection is not divine
2. In essence, the instantiation of the tool class is not completed in the work class, but Outside the work class, that is, it is completed on the client
3. Since the instantiation of the tool class is completed on the client, it is in the work class, and there must be a receiver to save the instantiated tool object
4. At this time, the user can directly pass the tool object that has been instantiated on the client to the method of the work class in the form of parameters
5. This kind of object is directly passed in from the outside The way to reach the current working class is called dependency injection
The source code is as follows:
<?php //数据库操作类 class Db { //数据库连接 public function connect() { return '数据库连接成功<br>'; } } //数据验证类 class Validate { //数据验证 public function check() { return '数据验证成功<br>'; } } //视图图 class View { //内容输出 public function display() { return '用户登录成功'; } } //用户类 class User { //创建三个成员属性,用来保存本类所依赖的对象 protected $db = null; protected $validate = null; protected $view = ''; //用户登录操作 public function login(Db $db, Validate $validate, View $view) { //实例化Db类并调用connect()连接数据库 // $db = new Db(); echo $db->connect(); //实例化Validate类并调用check()进行数据验证 // $validate = new Validate(); echo $validate->check(); //实例化视图类并调用display()显示运行结果 // $view = new View(); echo $view->display(); } } //在客户端完成工具类的实例化(即工具类实例化前移) $db = new Db(); $validate = new Validate(); $view = new View(); //创建User类 $user = new User(); //调用User对象的login方法进行登录操作 // echo $user->login(); // 将该类依赖的外部对象以参数方式注入到当前方法中,当然,推荐以构造器方式注入最方便 echo '<h3>用依赖注入进行解藕:</h3>'; echo $user->login($db, $validate, $view);
Although the instantiation of dependent classes is moved forward to the client, the dependency problem between classes is solved
However, there are still several problems:
1. In order to make the working class User a normal tool, all required classes must be instantiated externally in advance;
2 .As long as instantiation is involved, the client (caller) must be very familiar with the details of these dependent classes, such as parameters and return values
Can the user be allowed to omit the steps of instantiating the dependent classes? Isn't this better and simpler?
When we call an external dependent class, we only need to give a class name and a method (constructor) to create an instance of the class?
That is: we only give: the class name, the method of creating a class instance, and nothing else.
We will use the "container technology" to implement this fool-like decoupling process
The above is the entire content of this article. I hope it will be helpful to everyone's study. For more related content, please pay attention to the PHP Chinese website!
Related recommendations:
The above is the detailed content of Let's talk about dependency injection, containers and appearance patterns in framework development (Part 1). For more information, please follow other related articles on the PHP Chinese website!