摘要:如果在設(shè)計(jì)中,能正確使用開放封閉原則,就能很好的規(guī)避這些問題。開放封閉原則設(shè)計(jì)原則中的開放封閉原則是指代碼對(duì)擴(kuò)展開放,對(duì)修改關(guān)閉。實(shí)探我們以上章中的為基礎(chǔ),繼續(xù)來探究開放封閉原則。在進(jìn)一步處理之前,要知道開閉原則并非硬規(guī)定。
聲明:本文并非博主原創(chuàng),而是來自對(duì)《Laravel 4 From Apprentice to Artisan》閱讀的翻譯和理解,當(dāng)然也不是原汁原味的翻譯,能保證90%的原汁性,另外因?yàn)槭抢斫夥g,肯定會(huì)有錯(cuò)誤的地方,歡迎指正。
歡迎轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)注明出處,謝謝!
開放封閉原則 簡介在項(xiàng)目的整個(gè)生命周期中,絕大多數(shù)時(shí)間是在現(xiàn)有代碼上的維護(hù),而不是整天都在寫新功能。你會(huì)意識(shí)到,這是一個(gè)讓人頭大的過程。任何對(duì)代碼的修改,都會(huì)帶來破壞原有設(shè)計(jì),引入新bug的風(fēng)險(xiǎn)。理想狀態(tài)下,我們應(yīng)是像寫新代碼一樣,去快速簡單的修改老的邏輯。如果在設(shè)計(jì)中,能正確使用開放封閉原則,就能很好的規(guī)避這些問題。
實(shí)探開放封閉原則
SOLID設(shè)計(jì)原則中的開放封閉原則是指代碼對(duì)擴(kuò)展開放,對(duì)修改關(guān)閉。
我們以上章中的OrderProcessor為基礎(chǔ),繼續(xù)來探究開放封閉原則。對(duì)于process方法中的邏輯:
$recent = $this->orders->getRecentOrderCount($order->account); if ($recent > 0) { throw new Exception("Duplicate order likely."); }
這段代碼非常好讀,使用依賴注入的方法也讓我們易于測試。但是,如果針對(duì)驗(yàn)證的業(yè)務(wù)規(guī)則發(fā)生改編了怎么辦?添加了新規(guī)則又怎么辦?事實(shí)上,隨著業(yè)務(wù)的發(fā)展,肯定會(huì)出現(xiàn)_很多_新的規(guī)則!process方法會(huì)很快的變得癰腫起來而難以維護(hù)。因?yàn)閺拈_放封閉原則的角度考慮,他對(duì)修改是開放的,所以每當(dāng)需求變更我們都要對(duì)代碼進(jìn)行改變。牢記,我們期望的是對(duì)_擴(kuò)展_開放,而不是對(duì)修改開放。
代替掉在process中直接使用訂單驗(yàn)證的方式,我們定義一個(gè)新接口OrderValidator:
interface OrderValidatorInterface { public function validate(Order $order); }
接下來,創(chuàng)建對(duì)重復(fù)訂單驗(yàn)證的接口實(shí)現(xiàn):
class RecentOrderValidator implements OrderValidatorInterface { public function __construct(OrderRepository $orders) { $this->orders = $orders; } public function validate(Order $order) { $recent = $this->orders->getRecentOrderCount($order->account); if ($recent > 0) { throw new Exception("Duplicate order likely."); } } }
很好!現(xiàn)在一個(gè)小而可測的多帶帶的業(yè)務(wù)規(guī)則封裝類就完成了。我們來在創(chuàng)建一個(gè)檢測用戶是否被停用的接口實(shí)現(xiàn):
class SuspendedAccountValidator implememts OrderValidatorInterface { public function validate(Order $order) { if ($order->account->isSuspended()) { throw new Exception("Suspended accounts may not order.") } } }
現(xiàn)在我們有了兩個(gè)對(duì)接口OrderValidatorInterface的實(shí)現(xiàn)類,來看看怎么在OrderValidatorInterface中使用他們。我們只需在訂單處理類實(shí)例化時(shí)注入驗(yàn)證類,這樣就能在原有的訂單處理代碼基礎(chǔ)上輕松的添加或刪除驗(yàn)證規(guī)則。
class OrderProcessor { public function __construct(BillerInterface $biller, OrderRepository $orders, array $validators = array()) { $this->biller = $biller; $this->orders = $orders; $this->validators = $validators; } }
接下來,只需要在process方法中接入驗(yàn)證即可:
public function process(Order $order) { foreach ($this->validators as $validator) { $validator->validate($order); } // Process valid order... }
最后,我們須要將OrderProcessor綁定到應(yīng)用程序IoC容器中:
App::bind("OrderProcessor", function() { return new OrderProcessor( App::make("BillerInterface"), App::make("OrderRepository"), array( App::make("RecentOrderValidator"), App::make("SuspendedAccountValidator"), ), ); });
這些改變,只是在原有代碼上產(chǎn)生最小的影響,我們現(xiàn)在就能不改變?cè)瓉泶a的基礎(chǔ)上隨便添加或者刪除新的驗(yàn)證規(guī)則。
每個(gè)新的驗(yàn)證規(guī)則只是對(duì)OrderValidatorInterface的實(shí)現(xiàn),并注入到容器中。不用對(duì)原來那種龐大臃腫的process方法進(jìn)行單元測試,現(xiàn)在只需多帶帶的對(duì)新驗(yàn)證規(guī)則測試即可?,F(xiàn)在代碼就是對(duì)擴(kuò)展_開放_(tái),對(duì)_修改_關(guān)閉。
玉有瑕疵
要注意依賴關(guān)系的實(shí)現(xiàn)細(xì)節(jié)。當(dāng)依賴中的實(shí)現(xiàn)細(xì)節(jié)改變時(shí),用戶邏輯是不應(yīng)該更隨著改變的。當(dāng)這種情況發(fā)生時(shí),我們認(rèn)為實(shí)現(xiàn)細(xì)節(jié)在以來關(guān)系中是“有漏洞的”。當(dāng)抽象邏輯有漏洞,那么開閉原則也要被打破了。
在進(jìn)一步處理之前,要知道開閉原則并非硬規(guī)定。不是代碼的所有地方都得支持“熱插拔”。例如,那種規(guī)模很小,只是簡單的獲取幾行MySQL數(shù)據(jù)庫數(shù)據(jù)的邏輯并不須要你嚴(yán)格按照那些設(shè)計(jì)原則去編寫代碼。不要只是為了用而在編碼中硬賽上這些設(shè)計(jì)原則,這反而讓你的系統(tǒng)過度設(shè)計(jì),變得臃腫。很多設(shè)計(jì)原則是為了解決大而復(fù)雜系統(tǒng)時(shí)提出的常用解決方案。但是,別拿這些話作為你偷懶的借口。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/23005.html
摘要:它是良好應(yīng)用設(shè)計(jì)的大原則,包含單一責(zé)任原則開放封閉原則里氏替換原則接口分離原則依賴倒置原則讓我們通過代碼示例來深究下這五個(gè)原則。實(shí)探單一責(zé)任原則代表一個(gè)類有且僅有一個(gè)改變的原因,換言之,一個(gè)類的職責(zé)范疇是嚴(yán)謹(jǐn)明確的。 聲明:本文并非博主原創(chuàng),而是來自對(duì)《Laravel 4 From Apprentice to Artisan》閱讀的翻譯和理解,當(dāng)然也不是原汁原味的翻譯,能保證90%的原...
摘要:在改變存儲(chǔ)系統(tǒng)的情況下,必須對(duì)進(jìn)行修改,違背了開放封閉原則。傳統(tǒng)的依賴痛過倒置就能事代碼變得非常靈活,易于改變 聲明:本文并非博主原創(chuàng),而是來自對(duì)《Laravel 4 From Apprentice to Artisan》閱讀的翻譯和理解,當(dāng)然也不是原汁原味的翻譯,能保證90%的原汁性,另外因?yàn)槭抢斫夥g,肯定會(huì)有錯(cuò)誤的地方,歡迎指正。 歡迎轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)注明出處,謝謝! 依賴反轉(zhuǎn)原則 ...
摘要:暴露接口如果是函數(shù),就擴(kuò)展,否則就是驗(yàn)證數(shù)據(jù)使用金額校驗(yàn)規(guī)則這樣運(yùn)行能正常,也有擴(kuò)展性性,但是對(duì)于代碼潔癖的來說,這樣寫法不優(yōu)雅。 重構(gòu)不是對(duì)以前代碼的全盤否定,而是利用更好的方式,寫出更好,更有維護(hù)性代碼。不斷的追求與學(xué)習(xí),才有更多的進(jìn)步。 1.前言 做前端開發(fā)有一段時(shí)間了,在這段時(shí)間里面,對(duì)于自己的要求,不僅僅是項(xiàng)目能完成,功能正常使用這一層面上。還盡力的研究怎么寫出優(yōu)雅的代碼,性...
摘要:如果看不懂的話,可以在評(píng)論區(qū)中提問,我會(huì)第一時(shí)間回答你無論何時(shí)我一直都在嗯哼該文章屬于編程中的那些經(jīng)典套路設(shè)計(jì)模式匯總系列 在正式閱讀前,我先談?wù)勎覀冊(cè)撚檬裁醋藙莺托膽B(tài)學(xué)習(xí)設(shè)計(jì)模式: 如果你還沒有過多的編程經(jīng)驗(yàn)(泛指半年以下),我建議你把它當(dāng)做小說來看,能看懂多少是多少,因?yàn)榘肽暌韵陆?jīng)驗(yàn)的程序員用到設(shè)計(jì)模式的情況只會(huì)出現(xiàn)在面試上,至于實(shí)際工作中?相對(duì)來說這部分不會(huì)由你負(fù)責(zé)。 如果你已...
摘要:可以為服務(wù)提供者的方法設(shè)置類型提示。方法將在所有其他服務(wù)提供者均已注冊(cè)之后調(diào)用。所有服務(wù)提供者都在配置文件中注冊(cè)??梢赃x擇推遲服務(wù)提供者的注冊(cè),直到真正需要注冊(cè)綁定時(shí),這樣可以提供應(yīng)用程序的性能。 本文最早發(fā)布于 Rootrl的Blog 導(dǎo)言 Laravel是一款先進(jìn)的現(xiàn)代化框架,里面有一些概念非常重要。在上手Laravel之前,我認(rèn)為先弄懂這些概念是很有必要的。你甚至需要重溫下PHP...
閱讀 1269·2021-11-19 09:40
閱讀 3128·2021-11-02 14:47
閱讀 3101·2021-10-11 10:58
閱讀 3224·2019-08-30 15:54
閱讀 2678·2019-08-30 12:50
閱讀 1732·2019-08-29 16:54
閱讀 473·2019-08-29 15:38
閱讀 1243·2019-08-29 15:19