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