![關(guān)于依賴注入在PHP框架中的應(yīng)用_第1頁](http://file3.renrendoc.com/fileroot_temp3/2022-3/9/96c193d4-5d76-4c23-903f-8df1bbb3be79/96c193d4-5d76-4c23-903f-8df1bbb3be791.gif)
![關(guān)于依賴注入在PHP框架中的應(yīng)用_第2頁](http://file3.renrendoc.com/fileroot_temp3/2022-3/9/96c193d4-5d76-4c23-903f-8df1bbb3be79/96c193d4-5d76-4c23-903f-8df1bbb3be792.gif)
![關(guān)于依賴注入在PHP框架中的應(yīng)用_第3頁](http://file3.renrendoc.com/fileroot_temp3/2022-3/9/96c193d4-5d76-4c23-903f-8df1bbb3be79/96c193d4-5d76-4c23-903f-8df1bbb3be793.gif)
![關(guān)于依賴注入在PHP框架中的應(yīng)用_第4頁](http://file3.renrendoc.com/fileroot_temp3/2022-3/9/96c193d4-5d76-4c23-903f-8df1bbb3be79/96c193d4-5d76-4c23-903f-8df1bbb3be794.gif)
![關(guān)于依賴注入在PHP框架中的應(yīng)用_第5頁](http://file3.renrendoc.com/fileroot_temp3/2022-3/9/96c193d4-5d76-4c23-903f-8df1bbb3be79/96c193d4-5d76-4c23-903f-8df1bbb3be795.gif)
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)
文檔簡介
1、關(guān)于依賴注入在PHP框架中的應(yīng)用現(xiàn)在的 PHP 應(yīng)用包含了很多對象。有的對象能幫你發(fā)送電子郵件,另一個可以幫你把數(shù)據(jù)持久化到數(shù)據(jù)庫中。在你的應(yīng)用中,你可能會創(chuàng)建一個管理產(chǎn)品庫存的對象,或者是一個處理第三方 API 數(shù)據(jù)的對象。這篇文章中,我們的關(guān)注這件事情:應(yīng)用做了很多事情,它組織了很多對象來處理每一個任務(wù)。在 PHP 的 Symfony 2 框架中,有一個特殊的對象,幫助你實例化、組織和獲取應(yīng)用中的那一系列的對象。它叫 Service Container(服務(wù)容器),可以讓你標(biāo)準(zhǔn)化和集中化地創(chuàng)建應(yīng)用中對象。容器讓生活簡化,它速度很快,包含的架構(gòu)思想促進代碼的重用和解耦。所有 Symfony
2、2 的核心的類都使用容器,容器為框架的速度和可擴展性做了最大的貢獻。先來了解下什么是 Service。簡單的說,一個 Service 就是任何的可以完成某類“全局”任務(wù)的 PHP 對象。一個 Service 是一個 PHP 對象的通用性的術(shù)語,這個對象能執(zhí)行特定的任務(wù),通常被“全局”地使用,比如一個數(shù)據(jù)庫連接的對象,或者一個能發(fā)送電子郵件的對象。如果擁有很多松耦合的 Service,我們就說這個應(yīng)用遵循了 SOA(面向服務(wù)的架構(gòu))。創(chuàng)建一個 Service 很簡單,你只要為那份能完成特定任務(wù)的代碼寫個類,就 OK 了。一般來說,PHP 對象如果要成為 Service,必須要在應(yīng)用中被全局的使用
3、。比如一個 Mailer Service 被全局的用于發(fā)送電子郵件,但是由 Mailer 發(fā)送的郵件內(nèi)容對象(每次的內(nèi)容都不同)就不是 Service。既然 Service 這么容易創(chuàng)建,那有啥了不起的呢?如果你開始考慮將應(yīng)用中的每個功能都分離開來,你就能開始感受 Service 的好處了。因為每個 Service 只做一個工作,你在任何地方都可以輕松地獲得并使用它們的功能。每個 Service 也能更容易的被測試和配置,因為在應(yīng)用中它們是互相分離的。將你的應(yīng)用組織成一系列獨立的 Service 的類,也是面向?qū)ο缶幊痰淖罴褜嵺`之一。這種技能在任何開發(fā)語言中都是好程序員的標(biāo)志。什么是 Serv
4、ice Container。Service Container 也叫 Dependency Injection Container(依賴注入容器),就是一個簡單的 PHP 對象,管理著 Service 們的實例化。假設(shè)你有個發(fā)送電子郵件的 PHP 類。如果不用 Service Container,在你需要它時,都必須手工地創(chuàng)建對象。這也算簡單。但是,如果你不想重復(fù)地去配置它,就可以把它作為 Service。當(dāng)你需要創(chuàng)建一個 Service,它依賴了 Service Container 中一個或幾個其他的 Service 們時,你才會意識到容器的強大。假設(shè)你的一個新的 Service,依賴了發(fā)送
5、電子郵件的 Service。只要在新的 Service 配置中將發(fā)送電子郵件的 Service 設(shè)為參數(shù)即可,如果你的這個 Service 后來做了改動,需要再依賴一個 Service,只需要改下配置,增加參數(shù)即可。對應(yīng)到依賴注入模式,其實 Service Container 就是注入器;Service A 依賴 Service B,前者是依賴者,后者是被依賴者;被依賴者的接口一般就是依賴的定義。這次設(shè)計模式解決的是整個框架的架構(gòu)問題,解決了:功能間的松耦合、框架的擴展性,運行效率也高。其實還是蠻羨慕學(xué) Java 的同學(xué),很早就接觸一些好的設(shè)計和應(yīng)用,比如:Spring 框架。當(dāng)然現(xiàn)在 PHP
6、 的新的框架層出不窮,也借鑒各種好的思想。面包和牛奶已經(jīng)有了,可以吃了。看Laravel的IoC容器文檔只是介紹實例,但是沒有說原理,之前用MVC框架都沒有在意這個概念,無意中在phalcon的文檔中看到這個詳細的介紹,感覺豁然開朗,復(fù)制粘貼過來,主要是好久沒有寫東西了,現(xiàn)在確實很懶變得!首先,我們假設(shè),我們要開發(fā)一個組件命名為SomeComponent。這個組件中現(xiàn)在將要注入一個數(shù)據(jù)庫連接。在這個例子中,數(shù)據(jù)庫連接在component中被創(chuàng)建,這種方法是不切實際的,這樣做的話,我們將不能改變數(shù)據(jù)庫連接參數(shù)及數(shù)據(jù)庫類型等一些參數(shù)。php view plaincopy1. <?p
7、hp 2. 3. class SomeComponent 4. 5. 6. /* 7. * The instantiation of the connection is hardcoded inside 8.
8、0;* the component so is difficult to replace it externally 9. * or change its behavior 10. */ 11. public function someDb
9、Task() 12. 13. $connection = new Connection(array( 14. "host" => "localhost&quo
10、t;, 15. "username" => "root", 16. "password" => "secret",
11、;17. "dbname" => "invo" 18. ); 19. 20. / . 21.
12、160; 22. 23. 24. 25. $some = new SomeComponent(); 26. $some->someDbTask(); 為了解決上面所說的問題,我們需要在使用前創(chuàng)建一個外部連接,并注入到容器中。就目前而言,這看起來是一個很好的解決方案:php view plaincopy1. <?php 2. 3
13、. class SomeComponent 4. 5. 6. protected $_connection; 7. 8. /* 9. * Sets the connection externally 10.
14、160; */ 11. public function setConnection($connection) 12. 13. $this->_connection = $connection; 14.
15、 15. 16. public function someDbTask() 17. 18. $connection = $this->_connection; 19. 20.
16、 / . 21. 22. 23. 24. 25. $some = new SomeComponent(); 26. 27. /Create the connection 28. $connection = new Connection(arr
17、ay( 29. "host" => "localhost", 30. "username" => "root", 31. "password" => "secret",
18、32. "dbname" => "invo" 33. ); 34. 35. /Inject the connection in the component 36. $some->setConnection($connection); 37. 38. $some->someDbTask()
19、; 現(xiàn)在我們來考慮一個問題,我們在應(yīng)用程序中的不同地方使用此組件,將多次創(chuàng)建數(shù)據(jù)庫連接。使用一種類似全局注冊表的方式,從這獲得一個數(shù)據(jù)庫連接實例,而不是使用一次就創(chuàng)建一次。php view plaincopy1. <?php 2. 3. class Registry 4. 5. 6. /* 7. * Ret
20、urns the connection 8. */ 9. public static function getConnection() 10. 11. return new Connection(array(
21、160; 12. "host" => "localhost", 13. "username" => "root", 14. &
22、#160; "password" => "secret", 15. "dbname" => "invo" 16.
23、 ); 17. 18. 19. 20. 21. class SomeComponent 22. 23. 24. protected $_connection; 25. 26.
24、160; /* 27. * Sets the connection externally 28. */ 29. public function setConnection($connection) 30.
25、0; $this->_connection = $connection; 31. 32. 33. public function someDbTask() 34. 35. $connect
26、ion = $this->_connection; 36. 37. / . 38. 39. 40. 41. 42. $some = new SomeComponent(); 43.
27、;44. /Pass the connection defined in the registry 45. $some->setConnection(Registry:getConnection(); 46. 47. $some->someDbTask(); 現(xiàn)在,讓我們來想像一下,我們必須在組件中實現(xiàn)兩個方法,首先需要創(chuàng)建一個新的數(shù)據(jù)庫連接,第二個總是獲得一個共享連接:php view plaincopy1. <?p
28、hp 2. 3. class Registry 4. 5. 6. protected static $_connection; 7. 8. /* 9. * Creates a connection 10
29、. */ 11. protected static function _createConnection() 12. 13. return new Connection(array( 14.
30、160; "host" => "localhost", 15. "username" => "root", 16.
31、; "password" => "secret", 17. "dbname" => "invo" 18.
32、0; ); 19. 20. 21. /* 22. * Creates a connection only once and returns it 23. */ 24. &
33、#160; public static function getSharedConnection() 25. 26. if (self:$_connection=null) 27.
34、$connection = self:_createConnection(); 28. self:$_connection = $connection; 29. 30.
35、; return self:$_connection; 31. 32. 33. /* 34. * Always returns a new connection 35. */ 36.
36、60; public static function getNewConnection() 37. 38. return self:_createConnection(); 39. 40. 41. 42.
37、 43. class SomeComponent 44. 45. 46. protected $_connection; 47. 48. /* 49. * Sets the connection externally 50.
38、 */ 51. public function setConnection($connection) 52. $this->_connection = $connection; 53. 54.
39、0;55. /* 56. * This method always needs the shared connection 57. */ 58. public function someDbTask() 59.
40、60; 60. $connection = $this->_connection; 61. 62. / . 63. 64. 65.
41、60; /* 66. * This method always needs a new connection 67. */ 68. public function someOtherDbTask($connection) 69. &
42、#160; 70. 71. 72. 73. 74. 75. $some = new SomeComponent(); 76. 77. /This injects the shared connection 78. $some->setConnection(Regis
43、try:getSharedConnection(); 79. 80. $some->someDbTask(); 81. 82. /Here, we always pass a new connection as parameter 83. $some->someOtherDbTask(Registry:getConnection(); 到此為止,我們已經(jīng)看到了如何使用依
44、賴注入解決我們的問題。不是在代碼內(nèi)部創(chuàng)建依賴關(guān)系,而是讓其作為一個參數(shù)傳遞,這使得我們的程序更容易維護,降低程序代碼的耦合度,實現(xiàn)一種松耦合。但是從長遠來看,這種形式的依賴注入也有一些缺點。例如,如果組件中有較多的依賴關(guān)系,我們需要創(chuàng)建多個setter方法傳遞,或創(chuàng)建構(gòu)造函數(shù)進行傳遞。另外,每次使用組件時,都需要創(chuàng)建依賴組件,使代碼維護不太易,我們編寫的代碼可能像這樣:php view plaincopy1. <?php 2. 3. /Create the dependencies or re
45、trieve them from the registry 4. $connection = new Connection(); 5. $session = new Session(); 6. $fileSystem = new FileSystem(); 7. $filter = new Filter(); 8. $selec
46、tor = new Selector(); 9. 10. /Pass them as constructor parameters 11. $some = new SomeComponent($connection, $session, $fileSystem, $filter, $selector); 12. 13. / .
47、0;or using setters 14. 15. $some->setConnection($connection); 16. $some->setSession($session); 17. $some->setFileSystem($fileSystem); 18. $some->setFilter($filter); 19. $some->setSelector($selector);
48、60;我想,我們不得不在應(yīng)用程序的許多地方創(chuàng)建這個對象。如果你不需要依賴的組件后,我們又要去代碼注入部分移除構(gòu)造函數(shù)中的參數(shù)或者是setter方法。為了解決這個問題,我們再次返回去使用一個全局注冊表來創(chuàng)建組件。但是,在創(chuàng)建對象之前,它增加了一個新的抽象層:php view plaincopy1. <?php 2. 3. class SomeComponent 4. 5. 6. / . &
49、#160;7. 8. /* 9. * Define a factory method to create SomeComponent instances injecting its dependencies 10. */ 11. &
50、#160; public static function factory() 12. 13. 14. $connection = new Connection(); 15. $session
51、0;= new Session(); 16. $fileSystem = new FileSystem(); 17. $filter = new Filter(); 18.
52、160;$selector = new Selector(); 19. 20. return new self($connection, $session, $fileSystem, $filter, $selector); 21. 22. 23.
53、 這一刻,我們好像回到了問題的開始,我們正在創(chuàng)建組件內(nèi)部的依賴,我們每次都在修改以及找尋一種解決問題的辦法,但這都不是很好的做法。一種實用和優(yōu)雅的來解決這些問題,是使用容器的依賴注入,像我們在前面看到的,容器作為全局注冊表,使用容器的依賴注入做為一種橋梁來解決依賴可以使我們的代碼耦合度更低,很好的降低了組件的復(fù)雜性:php view plaincopy1. <?php 2. 3. class SomeComponent 4. 5.
54、6. protected $_di; 7. 8. public function _construct($di) 9. 10. $this->_di = $di; 11.
55、60; 12. 13. public function someDbTask() 14. 15. 16. / Get the connection service 17. &
56、#160; / Always returns a new connection 18. $connection = $this->_di->get('db'); 19. 20. 21.
57、; 22. public function someOtherDbTask() 23. 24. 25. / Get a shared connection service, 26.
58、60; / this will return the same connection everytime 27. $connection = $this->_di->getShared('db'); 28. 29.
59、0; /This method also requires a input filtering service 30. $filter = $this->_db->get('filter'); 31. 32. 33.
60、60; 34. 35. 36. $di = new PhalconDI(); 37. 38. /Register a "db" service in the container 39. $di->set('db', function() 40. return
61、160;new Connection(array( 41. "host" => "localhost", 42. "username" => "root", 43.
62、; "password" => "secret", 44. "dbname" => "invo" 45. ); 46. ); 47. 48. /Regis
63、ter a "filter" service in the container 49. $di->set('filter', function() 50. return new Filter(); 51. ); 52. 53. /Register a "session"
64、; service in the container 54. $di->set('session', function() 55. return new Session(); 56. ); 57. 58. /Pass the service container as unique par
65、ameter 59. $some = new SomeComponent($di); 60. 61. $some->someTask(); 現(xiàn)在,該組件只有訪問某種service的時候才需要它,如果它不需要,它甚至不初始化,以節(jié)約資源。該組件是高度解耦。他們的行為,或者說他們的任何其他方面都不會影響到組件本身。我們的實現(xiàn)辦法PhalconDI 是一個實現(xiàn)了服務(wù)的依賴注入功能的組件,它本身也是一個容器。由于Phalcon高度解耦,PhalconDI 是框架用來集成其他組件
66、的必不可少的部分,開發(fā)人員也可以使用這個組件依賴注入和管理應(yīng)用程序中不同類文件的實例?;旧?,這個組件實現(xiàn)了 Inversion of Control 模式?;诖?,對象不再以構(gòu)造函數(shù)接收參數(shù)或者使用setter的方式來實現(xiàn)注入,而是直接請求服務(wù)的依賴注入。這就大大降低了整體程序的復(fù)雜性,因為只有一個方法用以獲得所需要的一個組件的依賴關(guān)系。此外,這種模式增強了代碼的可測試性,從而使它不容易出錯。在容器中注冊服務(wù)¶框架本身或開發(fā)人員都可以注冊服務(wù)。當(dāng)一個組件A要求調(diào)用組件B(或它的類的一個實例),可以從容器中請求調(diào)用組件B,而不是創(chuàng)建組件B的一個實例。這種工作方式為我們提供了許多優(yōu)點:
67、我們可以更換一個組件,從他們本身或者第三方輕松創(chuàng)建。在組件發(fā)布之前,我們可以充分的控制對象的初始化,并對對象進行各種設(shè)置。我們可以使用統(tǒng)一的方式從組件得到一個結(jié)構(gòu)化的全局實例服務(wù)可以通過以下幾種方式注入到容器:php view plaincopy1. <?php 2. 3. /Create the Dependency Injector Container 4. $di = new PhalconDI(); 5.
68、60; 6. /By its class name 7. $di->set("request", 'PhalconHttpRequest'); 8. 9. /Using an anonymous function, the instance will lazy loaded 10. $di->set("request&q
69、uot;, function() 11. return new PhalconHttpRequest(); 12. ); 13. 14. /Registering directly an instance 15. $di->set("request", new PhalconHttpRequest(); 16.
70、 17. /Using an array definition 18. $di->set("request", array( 19. "className" => 'PhalconHttpRequest' 20. ); 在上面的例子中,當(dāng)向框架請求訪問一個請求數(shù)據(jù)時,它將首先確定容器中是否存在這個”reqeus
71、t”名稱的服務(wù)。容器會反回一個請求數(shù)據(jù)的實例,開發(fā)人員最終得到他們想要的組件。在上面示例中的每一種方法都有優(yōu)缺點,具體使用哪一種,由開發(fā)過程中的特定場景來決定的。用一個字符串來設(shè)定一個服務(wù)非常簡單,但缺少靈活性。設(shè)置服務(wù)時,使用數(shù)組則提供了更多的靈活性,而且可以使用較復(fù)雜的代碼。lambda函數(shù)是兩者之間一個很好的平衡,但也可能導(dǎo)致更多的維護管理成本。PhalconDI 提供服務(wù)的延遲加載。除非開發(fā)人員在注入服務(wù)的時候直接實例化一個對象,然后存存儲到容器中。在容器中,通過數(shù)組,字符串等方式存儲的服務(wù)都將被延遲加載,即只有在請求對象的時候才被初始化。php view plaincopy
72、1. <?php 2. 3. /Register a service "db" with a class name and its parameters 4. $di->set("db", array( 5. "className" => "P
73、halconDbAdapterPdoMysql", 6. "parameters" => array( 7. "parameter" => array( 8.
74、0; "host" => "localhost", 9. "username" => "root", 10.
75、160; "password" => "secret", 11. "dbname" => "blog" 12. &
76、#160; ) 13. ) 14. ); 15. 16. /Using an anonymous function 17. $di->set("db", function() 18. return new
77、0;PhalconDbAdapterPdoMysql(array( 19. "host" => "localhost", 20. "username" => "root", 21.
78、160; "password" => "secret", 22. "dbname" => "blog" 23. ); 24. );
79、;以上這兩種服務(wù)的注冊方式產(chǎn)生相同的結(jié)果。然后,通過數(shù)組定義的,在后面需要的時候,你可以修改服務(wù)參數(shù):php view plaincopy1. <?php 2. 3. $di->setParameter("db", 0, array( 4. "host" => "localhost", 5.
80、160;"username" => "root", 6. "password" => "secret" 7. ); 從容器中獲得服務(wù)的最簡單方式就是使用”get”方法,它將從容器中返回一個新的實例:php view plaincopy1. <?php 2. $request = $d
81、i->get("request"); 或者通過下面這種魔術(shù)方法的形式調(diào)用:php view plaincopy1. <?php 2. 3. $request = $di->getRequest(); PhalconDI 同時允許服務(wù)重用,為了得到一個已經(jīng)實例化過的服務(wù),可以使用 getShared() 方法的形式來獲得服務(wù)。具體的 PhalconHttpRequest 請求示例:php view plaincopy1. <
82、?php 2. 3. $request = $di->getShared("request"); 參數(shù)還可以在請求的時候通過將一個數(shù)組參數(shù)傳遞給構(gòu)造函數(shù)的方式:php view plaincopy1. <?php 2. 3. $component = $di->get("MyComponent", array("some-parameter",&
83、#160;"other") 首先先別追究這個設(shè)計模式的定義,否則你一定會被說的云里霧里,筆者就是深受其害,百度了N多文章,都是從理論角度來描述,充斥著大量的生澀詞匯,要么就是java代碼描述的,也生澀。不管怎么樣,總算弄清楚一些了,下面就以php的角度來描述一下依賴注入這個概念。先假設(shè)我們這里有一個類,類里面需要用到數(shù)據(jù)庫連接,按照最最原始的辦法,我們可能是這樣寫這個類的:1. class example 2. 3. private
84、60;$_db;4.5. function _construct()6. include "./Lib/Db.php"7. $this->_db = new Db("localhost","root","123456",&q
85、uot;test");8. 9.10. function getList()11. $this->_db->query(".");/這里具體sql語句就省略不寫了12. 13. 復(fù)制代碼過程:在構(gòu)造函數(shù)里先將數(shù)據(jù)庫類文件include進來;然后又通過new Db并傳入數(shù)據(jù)庫連接信息實例化db類;
86、之后getList方法就可以通過$this->_db來調(diào)用數(shù)據(jù)庫類,實現(xiàn)數(shù)據(jù)庫操作??瓷先ノ覀儗崿F(xiàn)了想要的功能,但是這是一個噩夢的開始,以后example1,example2,example3.越來越多的類需要用到db組件,如果都這么寫的話,萬一有一天數(shù)據(jù)庫密碼改了或者db類發(fā)生變化了,豈不是要回頭修改所有類文件?ok,為了解決這個問題,工廠模式出現(xiàn)了,我們創(chuàng)建了一個Factory方法,并通過Factory:getDb()方法來獲得db組件的實例:1. class Factory 2. public stati
87、c function getDb()3. include "./Lib/Db.php"4. return new Db("localhost","root","123456","test");5. 6.
88、60;復(fù)制代碼sample類變成:1. class example 2. 3. private $_db;4.5. function _construct()6. $this->_db = Factory:getDb();7. 8.9.
89、0; function getList()10. $this->_db->query(".");/這里具體sql語句就省略不寫了11. 12. 復(fù)制代碼這樣就完美了嗎?再次想想一下以后example1,example2,example3.所有的類,你都需要在構(gòu)造函數(shù)里通過Factory:getDb();獲的一個Db實例,實際上你由原來的直接與Db類的耦合變?yōu)榱撕虵a
90、ctory工廠類的耦合,工廠類只是幫你把數(shù)據(jù)庫連接信息給包裝起來了,雖然當(dāng)數(shù)據(jù)庫信息發(fā)生變化時只要修改Factory:getDb()方法就可以了,但是突然有一天工廠方法需要改名,或者getDb方法需要改名,你又怎么辦?當(dāng)然這種需求其實還是很操蛋的,但有時候確實存在這種情況,一種解決方式是:我們不從example類內(nèi)部實例化Db組件,我們依靠從外部的注入,什么意思呢?看下面的例子:1. class example 2. private $_db;3. function
91、160;getList()4. $this->_db->query(".");/這里具體sql語句就省略不寫了5. 6. /從外部注入db連接7. function setDb($connection)8. $this-&
92、gt;_db = $connection;9. 10. 11.12. /調(diào)用13. $example = new example();14. $example->setDb(Factory:getDb();/注入db連接15. $example->getList();復(fù)制代碼這樣一來,example類完全與外部類解除耦合了,你可以看到Db類里面已經(jīng)沒有工廠方法或Db類的身影了。我們通過從外部調(diào)用example類的setDb方法,將連接實例直接注入進去。這樣exa
93、mple完全不用關(guān)心db連接怎么生成的了。這就叫依賴注入,實現(xiàn)不是在代碼內(nèi)部創(chuàng)建依賴關(guān)系,而是讓其作為一個參數(shù)傳遞,這使得我們的程序更容易維護,降低程序代碼的耦合度,實現(xiàn)一種松耦合。這還沒完,我們再假設(shè)example類里面除了db還要用到其他外部類,我們通過:1. $example->setDb(Factory:getDb();/注入db連接2. $example->setFile(Factory:getFile();/注入文件處理類3. $example->setImage(Factory:getImage();/注入Image處理類4. .復(fù)制代碼我們沒完沒了
94、的寫這么多set?累不累?ok,為了不用每次寫這么多行代碼,我們又去弄了一個工廠方法:1. class Factory 2. public static function getExample()3. $example = new example();4. $example-&g
95、t;setDb(Factory:getDb();/注入db連接5. $example->setFile(Factory:getFile();/注入文件處理類6. $example->setImage(Factory:getImage();/注入Image處理類7. return $expa
96、mple;8. 9.10. 復(fù)制代碼實例化example時變?yōu)椋?. $example=Factory:getExample();2. $example->getList();復(fù)制代碼似乎完美了,但是怎么感覺又回到了上面第一次用工廠方法時的場景?這確實不是一個好的解決方案,所以又提出了一個概念:容器,又叫做IoC容器、DI容器。我們本來是通過setXXX方法注入各種類,代碼很長,方法很多,雖然可以通過一個工廠方法包裝,但是還不是那么爽,好吧,我們不用setXXX方法了,這樣也就不用工廠方法二次包裝了,那么我們還怎么實現(xiàn)依賴注入呢?這里我們引入一個約定:在example類的構(gòu)造函數(shù)里傳入一個名為Di $di的參數(shù),如下:1. class example 2. private $_di;3. fu
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 個人抵押貸款合同季度范本
- 臨街店鋪購買合同范本
- 二次供水設(shè)備采購合同
- 專業(yè)服裝管理軟件經(jīng)銷合同書
- 上海市股權(quán)轉(zhuǎn)讓合同標(biāo)準(zhǔn)范本
- 二手房銷售代理合同協(xié)議
- 中外合作種植戰(zhàn)略合作合同
- 云計算服務(wù)提供商數(shù)據(jù)保密合同
- 返聘人員協(xié)議書
- IT行業(yè)員工培訓(xùn)勞動合同范本
- 小紅書種草營銷師(初級)認(rèn)證考試真題試題庫(含答案)
- 癲癇病人的護理(課件)
- 企業(yè)資產(chǎn)管理培訓(xùn)
- 2024年WPS計算機二級考試題庫350題(含答案)
- 2024年4月27日浙江省事業(yè)單位招聘《職業(yè)能力傾向測驗》試題
- 2024年6月浙江省高考地理試卷真題(含答案逐題解析)
- 醫(yī)院培訓(xùn)課件:《如何撰寫護理科研標(biāo)書》
- 風(fēng)車的原理小班課件
- 河南省鄭州市2023-2024學(xué)年高二上學(xué)期期末考試 數(shù)學(xué) 含答案
- 2024年山東省濟南市中考英語試題卷(含答案)
- 2024年北師大版八年級上冊全冊數(shù)學(xué)單元測試題含答案
評論
0/150
提交評論