This article mainly introduces the three realms of PHP decoupling (talking about service containers. It has good reference value. Next, let's take a look at it. This article mainly introduces the three realms of PHP decoupling (talking about service containers. It has good reference value. Let's take a look at it with the small editor.
Before reading this article, you need to understand: PHP syntax, object-oriented
In the process of completing the entire software project development, sometimes many people need to work together, and sometimes they can do it independently, no matter which one. as the amount of code increases, the writing will be "out of control, gradually "ugly interface, dirty implementation", the project maintenance cost and difficulty increased to a level that is hard to maintain, only reconstruction or redevelopment.
Level 1
Hypothesis: we need to write a processing class that can simultaneously operate sessions, databases, and file systems. We may write this.
Realm features: it can run but is heavily coupled
class DB{ public function DB($arg1,$arg2){ echo 'constructed!'.PHP_EOL; }}class FileSystem{ public function FileSystem($arg1,$arg2){ echo 'constructed!'.PHP_EOL; }}class Session{ public function Session($arg1,$arg2){ echo 'constructed!'.PHP_EOL; }}class Writer{ public function Write(){ $db=new DB(1,2); $filesystem=new FileSystem(3,4); $session=new Session(5,6); }}$writer=new Writer();$writer->write();
Disadvantages of writing:
1. construct an object in a public function. once the changes to database parameters are involved, it will take a lot of effort to modify the object.
2. persons responsible for designing Writer classes should be familiar with various APIs of DB and other classes.
Is there a way to reduce coupling?
Second Realm (parameter dependency)
Assume that the database address needs to be changed frequently because of different customers. There are many classes called to the database (if there are dozens of classes), even if the database address is changed, you do not need to modify the code of these classes.
class DB{ public function DB($arg1,$arg2){ echo 'constructed!'.PHP_EOL; }}class FileSystem{ public function FileSystem($arg1,$arg2){ echo 'constructed!'.PHP_EOL; }}class Session{ public function Session($arg1,$arg2){ echo 'constructed!'.PHP_EOL; }}class Writer{ protected $_db; protected $_filesystem; protected $_session; public function Set($db,$filesystem,$session){ $this->_db=$db; $this->_filesystem=$filesystem; $this->_session=$session; } public function Write(){ }}$db=new DB(1,2);$filesystem=new FileSystem(3,4);$session=new Session(5,6);$writer=new Writer();$writer->Set($db,$filesystem,$session);$writer->write();
Although the structure of the DB class is moved to the client, the workload is greatly reduced once the modification is involved, but a new problem arises: to create a Writer class, we need to first create a DB Class, FileSystem class, etc, this is very demanding for those responsible for the Writer class. He needs to read many other class documents and create them one by one (Initialization may also be required ), then the writer variable is created.
Therefore, we hope that there will be a better way of writing, so that the Writer class can be created and called using a more efficient interface, you do not even need to enter the parameter.
Third-party realm (IOC container)
After the first two important realms, we hope to add the following benefits:
1. you do not need to initialize the database class, Session class, and FileSystem class every time, such as $ DB = new db (arg1, arg2.
2. it is expected that DB and other types of objects are "global" and can be called at any time during the entire program running.
3. programmers who call DB and other types do not need to know the details of this class, or even use a string alias to create such an object.
To achieve the above goal, the IOC container can simply regard the IOC container as a global variable and bind the string and constructor with an associated array.
First, implement a container class.
class Container{ public $bindings; public function bind($abstract,$concrete){ $this->bindings[$abstract]=$concrete; } public function make($abstract,$parameters=[]){ return call_user_func_array($this->bindings[$abstract],$parameters); }}
Service registration (binding)
$container=new Container();$container->bind('db',function($arg1,$arg2){ return new DB($arg1,$arg2);});$container->bind('session',function($arg1,$arg2){ return new Session($arg1,$arg2);});$container->bind('fs',function($arg1,$arg2){ return new FileSystem($arg1,$arg2);});
Container dependency
class Writer{ protected $_db; protected $_filesystem; protected $_session; protected $container; public function Writer(Container $container){ $this->_db=$container->make('db',[1,2]); $this->_filesystem=$container->make('session',[3,4]); $this->_session=$container->make('fs',[5,6]); }}$writer=new Writer($container);
The above is the details of the sample code in the triple realm of PHP decoupling (talking about service containers). For more information, see other related articles in the first PHP community!