![五種常見的 PHP 設(shè)計模式_第1頁](http://file4.renrendoc.com/view/5b0bd5d7ea6c4487ecffd7a425afb041/5b0bd5d7ea6c4487ecffd7a425afb0411.gif)
![五種常見的 PHP 設(shè)計模式_第2頁](http://file4.renrendoc.com/view/5b0bd5d7ea6c4487ecffd7a425afb041/5b0bd5d7ea6c4487ecffd7a425afb0412.gif)
![五種常見的 PHP 設(shè)計模式_第3頁](http://file4.renrendoc.com/view/5b0bd5d7ea6c4487ecffd7a425afb041/5b0bd5d7ea6c4487ecffd7a425afb0413.gif)
![五種常見的 PHP 設(shè)計模式_第4頁](http://file4.renrendoc.com/view/5b0bd5d7ea6c4487ecffd7a425afb041/5b0bd5d7ea6c4487ecffd7a425afb0414.gif)
![五種常見的 PHP 設(shè)計模式_第5頁](http://file4.renrendoc.com/view/5b0bd5d7ea6c4487ecffd7a425afb041/5b0bd5d7ea6c4487ecffd7a425afb0415.gif)
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
五種常見的PHP設(shè)計模式設(shè)計模式一書將設(shè)計模式引入軟件社區(qū),該書的作者是ErichGamma、RichardHelm、RalphJohnson和JohnVlissidesDesign(俗稱“四人幫”)。所介紹的設(shè)計模式背后的核心概念非常簡單。經(jīng)過多年的軟件開發(fā)實踐,Gamma等人發(fā)現(xiàn)了某些具有固定設(shè)計的模式,就像建筑師設(shè)計房子和建筑物一樣,可以為浴室的位置或廚房的構(gòu)造方式開發(fā)模板。使用這些模板或者說設(shè)計模式意味著可以更快地設(shè)計更好的建筑物。同樣的概念也適用于軟件。設(shè)計模式不僅代表著更快開發(fā)健壯軟件的有用方法,而且還提供了以友好的術(shù)語封裝大型理念的方法。例如,您可以說您正在編寫一個提供松散耦合的消息傳遞系統(tǒng),也可以說你正在編寫名稱為觀察者的模式。用較小的示例展示模式的價值是非常困難的。這往往有些大材小用的意味,因為模式實際上是在大型代碼庫中發(fā)揮作用的。本文不展示大型應(yīng)用程序,所以您需要思索的是在您自己的大型應(yīng)用程序中應(yīng)用示例原理的方法一而不是本文演示的代碼本身。這不是說您不應(yīng)該在小應(yīng)用程序中使用模式。很多良好的應(yīng)用程序都以小應(yīng)用程序為起點,逐漸發(fā)展到大型應(yīng)用程序,所以沒有理由不以此類扎實的編碼實踐為基礎(chǔ)。既然您已經(jīng)了解了設(shè)計模式以及它們的有用之處,現(xiàn)在我們來看看PHPV5的五種常用模式。工廠模式最初在設(shè)計模式一書中,許多設(shè)計模式都鼓勵使用松散耦合。要理解這個概念,讓我們最好談一下許多開發(fā)人員從事大型系統(tǒng)的艱苦歷程。在更改一個代碼片段時,就會發(fā)生問題,系統(tǒng)其他部分一您曾認為完全不相關(guān)的部分中也有可能出現(xiàn)級聯(lián)破壞。該問題在于緊密耦合。系統(tǒng)某個部分中的函數(shù)和類嚴重依賴于系統(tǒng)的其他部分中函數(shù)和類的行為和結(jié)構(gòu)。您需要一組模式,使這些類能夠相互通信,但不希望將它們緊密綁定在一起,以避免出現(xiàn)聯(lián)鎖。在大型系統(tǒng)中,許多代碼依賴于少數(shù)幾個關(guān)鍵類。需要更改這些類時,可能會出現(xiàn)困難。例如,假設(shè)您有一個從文件讀取的User類。您希望將其更改為從數(shù)據(jù)庫讀取的其他類,但是,所有的代碼都引用從文件讀取的原始類。這時候,使用工廠模式會很方便。工廠模式是一種類,它具有為您創(chuàng)建對象的某些方法。您可以使用工廠類創(chuàng)建對象,而不直接使用new。這樣,如果您想要更改所創(chuàng)建的對象類型,只需更改該工廠即可。使用該工廠的所有代碼會自動更改。清單1顯示工廠類的一個示列。等式的服務(wù)器端包括兩個部分:數(shù)據(jù)庫和一組PHP頁面,這些頁面允許您添加反饋、請求反饋列表并獲取與特定反饋相關(guān)的文章。classUserimplementsIUser{publicfunction__construct($id){}publicfunctiongetName(){return"Jack";classUserFactory{publicstaticfunctionCreate($id){returnnewUser($id);}}$uo=UserFactory::Create(1);echo($uo->getName()."\n");?>IUser接口定義用戶對象應(yīng)執(zhí)行什么操作。IUser的實現(xiàn)稱為User,UserFactory工廠類則創(chuàng)建IUser對象。此關(guān)系可以用圖1中的UML表示。圖1.工廠類及其相關(guān)IUser接口和用戶類如果您使用php解釋器在命令行上運行此代碼,將得到如下結(jié)果:%phpfactory1.phpJack%測試代碼會向工廠請求User對象,并輸出getName方法的結(jié)果。有一種工廠模式的變體使用工廠方法。類中的這些公共靜態(tài)方法構(gòu)造該類型的對象。如果創(chuàng)建此類型的對象非常重要,此方法非常有用。例如,假設(shè)您需要先創(chuàng)建對象,然后設(shè)置許多屬性。此版本的工廠模式會將該進程封裝在單個位置中,這樣,不用復(fù)制復(fù)雜的初始化代碼,也不必將復(fù)制好的代碼在在代碼庫中到處粘貼。清單2顯示使用工廠方法的一個示例。清單2.Factory2.php<?phpinterfacelUserfunctiongetName();嚴UserimplementsIUserpublicstaticfunctionLoad($id)returnnewUser($id);5……)returnnewUser(null);『?}publicfunctiongetName()return"Jack";$uo=User::Load(1);echo($uo->getName()."\n");這段代碼要簡單得多。它僅有一個接口IUser和一個實現(xiàn)此接口的User類。User類有兩個創(chuàng)建對象的靜態(tài)方法。此關(guān)系可用圖2中的UML表示。圖2.IUser接口和帶有工廠方法的user類在命令行中運行腳本產(chǎn)生的結(jié)果與清單1的結(jié)果相同,如下所示:%phpfactory2.phpJack%如上所述,有時此類模式在規(guī)模較小的環(huán)境中似乎有些大材小用。不過,最好還是學(xué)習(xí)這種扎實的編碼形式,以便應(yīng)用于任意規(guī)模的項目中。單元素模式某些應(yīng)用程序資源是獨占的,因為有且只有一個此類型的資源。例如,通過數(shù)據(jù)庫句柄到數(shù)據(jù)庫的連接是獨占的。您希望在應(yīng)用程序中共享數(shù)據(jù)庫句柄,因為在保持連接打開或關(guān)閉時,它是一種開銷,在獲取單個頁面的過程中更是如此。單元素模式可以滿足此要求。如果應(yīng)用程序每次包含且僅包含一個對象,那么這個對象就是一個單元素(Singleton)。清單3中的代碼顯示了PHPV5中的一個數(shù)據(jù)庫連接單元素。清單3.Singleton.php<?phprequire_once("DB.php");classDatabaseConnection{publicstaticfunctionget(){static$db=null;if($db==null)$db=newDatabaseConnection();return$db;}private$_handle=null;privatefunction__construct(){$dsn='mysql://root:password@localhost/photos';$this->_handle=&DB::Connect($dsn,array());}publicfunctionhandle(){return$this->_handle;}}print("Handle=".DatabaseConnection::get()->handle()."\n");print("Handle=".DatabaseConnection::get()->handle()."\n");?>此代碼顯示名為Databaseconnection的單個類。您不能創(chuàng)建自已的Databaseconnection,因為構(gòu)造函數(shù)是專用的。但使用靜態(tài)get方法,您可以獲得且僅獲得一個Databaseconnection對象。此代碼的UML如圖3所示。圖3.數(shù)據(jù)庫連接單元素□AtabasaConnofticnSBti)卜a在兩次調(diào)用間,handle方法返回的數(shù)據(jù)庫句柄是相同的,這就是最好的證明。您可以在命令行中運行代碼來觀察這一點。%phpsingleton.phpHandle=Objectid#3Handle=Objectid#3%返回的兩個句柄是同一對象。如果您在整個應(yīng)用程序中使用數(shù)據(jù)庫連接單元素,那么就可以在任何地方重用同一句柄。您可以使用全局變量存儲數(shù)據(jù)庫句柄,但是,該方法僅適用于較小的應(yīng)用程序。在較大的應(yīng)用程序中,應(yīng)避免使用全局變量,并使用對象和方法訪問資源。觀察者模式觀察者模式為您提供了避免組件之間緊密耦合的另一種方法。該模式非常簡單:一個對象通過添加一個方法(該方法允許另一個對象,即觀察者注冊自己)使本身變得可觀察。當可觀察的對象更改時,它會將消息發(fā)送到已注冊的觀察者。這些觀察者使用該信息執(zhí)行的操作與可觀察的對象無關(guān)。結(jié)果是對象可以相互對話,而不必了解原因。一個簡單示例是系統(tǒng)中的用戶列表。清單4中的代碼顯示一個用戶列表,添加用戶時,它將發(fā)送出一條消息。添加用戶時,通過發(fā)送消息的日志觀察者可以觀察此列表。{functionaddObserver($observer);}classUserListimplementslObservable{private$_observers=array();publicfunctionaddCustomer($name){foreach($this->_observersas$obs)$obs->onChanged($this,$name);}publicfunctionaddObserver($observer){$this->_observers[]=$observer;}}classUserListLoggerimplementsIObserver{publicfunctiononChanged($sender,$args){echo("'$args'addedtouserlist\n");}}$ul=newUserList();$ul->addObserver(newUserListLogger());$ul->addCustomer("Jack");?>此代碼定義四個元素:兩個接口和兩個類。lObservable接口定義可以被觀察的對象,UserList實現(xiàn)該接口,以便將本身注冊為可觀察。IObserver列表定義要通過怎樣的方法才能成為觀察者,UserListLogger實現(xiàn)IObserver接口。圖4的UML中展示了這些元素。圖4.可觀察的用戶列表和用戶列表事件日志程序如果在命令行中運行它,您將看到以下輸出:%phpobserver.php'Jack'addedtouserlist%測試代碼創(chuàng)建UserList,并將UserListLogger觀察者添加到其中。然后添加一個消費者,并將這一更改通知UserListLogger。認識到UserList不知道日志程序?qū)?zhí)行什么操作很關(guān)鍵??赡艽嬖谝粋€或多個執(zhí)行其他操作的偵聽程序。例如,您可能有一個向新用戶發(fā)送消息的觀察者,歡迎新用戶使用該系統(tǒng)。這種方法的價值在于UserList忽略所有依賴它的對象,它主要關(guān)注在列表更改時維護用戶列表并發(fā)送消息這一工作。此模式不限于內(nèi)存中的對象。它是在較大的應(yīng)用程序中使用的數(shù)據(jù)庫驅(qū)動的消息查詢系統(tǒng)的基礎(chǔ)。命令鏈模式命令鏈模式以松散耦合主題為基礎(chǔ),發(fā)送消息、命令和請求,或通過一組處理程序發(fā)送任意內(nèi)容。每個處理程序都會自行判斷自己能否處理請求。如果可以,該請求被處理,進程停止。您可以為系統(tǒng)添加或移除處理程序,而不影響其他處理程序。清單5顯示了此模式的一個示例。清單5.Chain.php<?phpinterfaceICommand{functiononCommand($name,$args);}classCommandChain{private$_commands=array();publicfunctionaddCommand($cmd){$this->_commands[]=$cmd;}publicfunctionrunCommand($name,$args){foreach($this->_commandsas$cmd){if($cmd->onCommand($name,$args))return;}}}classUserCommandimplementsiCommand{publicfunctiononCommand($name,$args){if($name!='addUser')returnfalse;echo("UserCommandhandling'addUser'\n");returntrue;}}classMailCommandimplementsICommand{publicfunctiononCommand($name,$args){if($name!='mail')returnfalse;echo("MailCommandhandling'mail'\n");returntrue;}}$cc=newCommandChain();$cc->addCommand(newUserCommand());$cc->addCommand(newMailCommand());$cc->runCommand('addUser',null);$cc->runCommand('mail',null);?>此代碼定義維護ICommand對象列表的CommandChain類。兩個類都可以實現(xiàn)ICommand接口個對郵件的請求作出響應(yīng),另一個對添加用戶作出響應(yīng)。圖5給出了UML。圖5.命令鏈及其相關(guān)命令如果您運行包含某些測試代碼的腳本,則會得到以下輸出:%phpchain.phpUserCommandhandling'addUserMailCommandhandling'mail'%代碼首先創(chuàng)建CommandChain對象,并為它添加兩個命令對象的實例。然后運行兩個命令以查看誰對這些命令作出了響應(yīng)。如果命令的名稱匹配UserCommand或MailCommand,則代碼失敗,不發(fā)生任何操作。為處理請求而創(chuàng)建可擴展的架構(gòu)時,命令鏈模式很有價值,使用它可以解決許多問題。策略模式我們講述的最后一個設(shè)計模式是策略模式。在此模式中,算法是從復(fù)雜類提取的,因而可以方便地替換。例如,如果要更改搜索引擎中排列頁的方法,則策略模式是一個不錯的選擇。思考一下搜索引擎的幾個部分部分遍歷頁面,一部分對每頁排列,另一部分基于排列的結(jié)果排序。在復(fù)雜的示例中,這些部分都在同一個類中。通過使用策略模式,您可將排列部分放入另一個類中,以便更改頁排列的方式,而不影響搜索引擎的其余代碼。作為一個較簡單的示例,清單6顯示了一個用戶列表類,它提供了一個根據(jù)一組即插即用的策略查找一組用戶的方法。清單6.Strategy.php<?phpinterfaceIStrategy{functionfilter($record);}classFindAfterStrategyimplementsIStrategy{private$_name;publicfunction__construct($name){$this->_name=$name;}publicfunctionfilter($record){returnstrcmp($this->_name,$record)<=0;}}classRandomStrategyimplementsIStrategypublicfunctionfilter($record)returnrand(0,1)>=0.5;classUserListprivate$_list=array();publicfunction__construct($names)if($names!=null)foreach($namesas$name)$this->_list[]=$name;…addg)$this->_list[]=$name
溫馨提示
- 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)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年度家具安裝與室內(nèi)布局設(shè)計合同范本
- 2025年度文化設(shè)施建設(shè)項目施工合同代理詞
- 2025年度草莓種植技術(shù)培訓(xùn)與人才引進合同
- 2025年度換熱站節(jié)能改造項目咨詢合同
- 2025年度高端別墅庭院景觀綠化安裝服務(wù)合同
- 2025國際房地產(chǎn)買賣合同規(guī)范指南
- 2025年度教學(xué)樓門窗改造工程環(huán)保評估與監(jiān)管合同
- 2025年度個性化婚姻介紹服務(wù)合同樣本
- 2025年度國內(nèi)貿(mào)易代理合同(含數(shù)據(jù)安全)
- 2025年度智能醫(yī)療設(shè)備研發(fā)生產(chǎn)債權(quán)債務(wù)擔(dān)保合同
- 中興ZCTP 5GC高級工程師認證考試題庫匯總(含答案)
- 2023年考研考博-考博英語-西安建筑科技大學(xué)考試歷年真題摘選含答案解析
- 反接制動控制線路電路圖及工作原理
- MCNP-5A程序使用說明書
- java基礎(chǔ)知識大全
- SMM英國建筑工程標準計量規(guī)則中文 全套
- GB 18030-2022信息技術(shù)中文編碼字符集
- SB/T 10977-2013倉儲作業(yè)規(guī)范
- GB/T 854-1988單耳止動墊圈
- GB/T 2520-2017冷軋電鍍錫鋼板及鋼帶
- 【QC成果】提高地下室抗浮錨桿一次驗收合格率
評論
0/150
提交評論