摘要:控制只是用來接收請求并請求邏輯處理類。事實上,業務邏輯無需感知網絡,網絡僅僅接入應用的傳輸機制,他不應超出應用中的路由和控制器的范疇。職責分離是編寫健壯應用的關鍵。其他通常,類庫應該以規范組織在我們的應用中。
聲明:本文并非博主原創,而是來自對《Laravel 4 From Apprentice to Artisan》閱讀的翻譯和理解,當然也不是原汁原味的翻譯,能保證90%的原汁性,另外因為是理解翻譯,肯定會有錯誤的地方,歡迎指正。
歡迎轉載,轉載請注明出處,謝謝!
應用架構 簡介這一章是哪出戲?對于使用框架創建應用這是非常普遍的。很多開發者會提出這樣的問題,因為在他們腦仁里已經存在這樣的觀念,“模型”就是“數據庫”。所以通常,控制器被用來和HTTP交互,模型就是和數據庫_打交道_,視圖就是還有HTML代碼的那部分。但是,對于那些比如發送郵件的類、驗證數據類、訪問接口的類該怎么區分呢?本章我們就使用Laravel構建好的架構進行探討,打破那些固話在你心中的概念,讓開發回歸本質。
MVC會弄死你的阻礙我們的一種設計即:M-V-C。模型,視圖,控制器,這種框架思維已經控制開發人員很多年了。這種思維來源于Ruby On Rails。如果,讓一個程序員去解釋什么是“模型”,通常都會聽到將其和“數據庫”關聯的答案。據說,模型_就是_數據庫。模型包含了數據庫的一切。但是,很快你就會發現,在簡單的數據庫訪問類之上還有很多額外的邏輯。他需要我們進行數據驗證,調取額外的服務,發送郵件,等等。
什么是模型?
模型現在已經變的模棱兩可,很難具體指代什么。根據開發中遇到的那么多詞匯,我們可以理解認為,他就是為了將應用切分成小而清晰,具有特定職責的類。
那么,這種困境中的解決方案是什么?很多開發人員會在控制器之上添加更多的邏輯。當控制器變的很大的時候,需要復用其他控制器中的一些邏輯層。很多人會錯誤的認為_需要_在當前控制器調用其他控制器,而不是講邏輯抽象成多帶帶的類。這種模式通常稱為“HMVC”。不幸的是,這也是糟糕的設計,通常控制器會很復雜。
HMVC(通常)預示著糟糕的設計
當覺得須要在控制器中調用其他控制器?這意味著當前設計是糟糕的,控制器里面的業務邏輯太負責。我們可以講邏輯抽象成通用類,以便在其他控制器中進行調用。
總會有更好的程序設計。我們需要忘記以前在腦海中殘留的那種“模型”的設計理念,干脆讓我們刪除模型目錄,并重新開始。
再見,模型是否已經把你的models目錄刪除?如果沒有,沒關系,別再去理他。我們來在app下建立一個新文件夾,簡單的起個應用名字即可QuickBill,在后續的討論中,我們之前舉例的那些例子都會出現。
注意使用場景
記住,如果你創建的是小型的Laravel應用,在models下創建幾個Eloquent模型還是很合適的。而在本章中,我們關注的是擁有更多“層次”架構的復雜應用。
我們已經有了app/QuickBill目錄,他和controllers和views目錄同級。我們可以在QuickBill下創建一些其他目錄,比如Repositories和Billing目錄。建好目錄之后,記得在composer.json注冊PSR-0自動加載。
"autoload": { "psr-0": { "QuickBill": "app/" } }
現在,我們把Eloquent類放到QuickBill根目錄下,我們就能輕松的訪問到QuickBillUser,以及QuickBillPayment等。在Respositories目錄中創建PaymentRepository和UserRepository類,并編碼數據訪問的方法getRecentPayments以及getRichestUser。在Billing目錄則包含使用第三方服務,諸如“Stripe”、“Balanced”的類和接口。上述目錄結構如下:
// app // QuickBill // Repositories -> UserRepository.php -> PaymentRepository.php // Billing -> BillerInterface.php -> StripeBiller.php // Notifications -> BillingNotifierInterface.php -> SmsBillingNotifier.php User.php Payment.php
數據驗證放哪
這個問題通常讓我們頭大。可以考慮把他們放到“實體”類中,比如User.php或者Payment.php中,方法名可以叫:validForCreation和hasValidDomain。或者也可以創建一個命名空間為Validation的UserValidator類,并注入到repository類中。兩種方法看個人喜好。
擺脫models目錄,我們就能沖破枷鎖,實現好的設計。當然,我們創建的很多項目都會有相似之處,無論多么復雜的項目也都會有數據接入(存儲)層,以及其他服務層等等。
處處皆分層不要害怕文件夾
不要因為多建文件夾而害怕,他是組織應用程序的很好方式。通常我們希望以此講應用分割成很小的組件,每個組件都有自己特定的職責。別被“模型”束縛了思維。就像上面舉的例子,我們可以創建一個Repository來存放所有數據接入的相關類。
你應該已經注意到,好的應用設計應擁有明確的職責劃分,有明確的邏輯分成。控制只是用來接收HTTP請求并請求邏輯處理類。業務處理層_才是_整個應用的中心。它包含了像數據獲取,數據驗證,支付處理,郵件發送類庫,以及應用中的各種函數等。事實上,業務邏輯無需感知“網絡”,網絡僅僅接入應用的傳輸機制,他不應超出應用中的路由和控制器的范疇。好的架構是經得起考研的,是由清晰代碼組成的可持續發展的架構。
例如,我們使用向控制器中傳入網絡請求輸入來替代在類中直接訪問網絡請求實例的方法。簡單的改動即將類從“網絡”中解耦出來,這種方式也不用擔心在測試時對請求的再次模擬了:
class BillingController extends BaseController{ public function __construct(BillerInterface $biller) { $this->biller = $biller; } public function postCharge() { $this->biller->chargeAccount(Auth::user(), Input::get("amount")); return View::make("charge.success"); } }
chargeAccount方法可以很容易進行測試,只需傳入測試數據用到的整型數據,而不是使用一個含有Request和Input類的BillerInterface接口的實現類庫來作為參數傳入該方法。
職責分離是編寫健壯應用的關鍵。這種關鍵就是一個類是否管的太多。你應該時常問自己:“是不是這個類還要關心X?”,如果答案是“不”,就將邏輯抽象出來,并用依賴注入的方式處理。
“瓶瓶罐罐”都放哪改變的原因很簡單
決定類庫是否足夠職責分離的一個非常有用的方法就是檢驗自己為什么要更改這些代碼。比如,在調整通知邏輯的時候,是否Biller接口的實現也要修改?當然不,Biller的實現只和支付有關,只需按照約定和通知邏輯交互。保持這樣的思維觀念,就能幫你快速改進應用中的各個部分,使之變得健壯起來。
當使用Laravel開發應用的時候,會經常有這樣的疑問,很多“東西”不知道放哪。比如,“helper”函數放哪?事件堅挺程序放哪?視圖組件又該在哪?答案可能會讓你凌亂:“哪都可以”!Laravel沒有文件該歸屬哪里的概念。然而這個答案并不是讓人滿意的,在繼續深入之前,讓我們先就上面的問題探討下。
輔助函數Laravel的輔助函數放在support/helpers.php文件中。或者你也想創建這樣一個自己的輔助函數文件,“start”目錄就是個不錯的地方。在請求應用時,start/global.php都會被引用到,我們可以在這添加上加載自己的helpers.php文件:
// Within app/start/global.php require_once __DIR__."/../helpers.php";事件監聽器
事件監聽器當然不能屬于routes.php文件,放在start文件也不合適,我們要另擇地方安放他。服務提供器的目錄就不錯,之前我們知道,服務提供不僅是容器注冊綁定的服務,還可以做很多其他事情。它可以講很多監聽器組織起來,這種方式是代碼清理整潔,也不影響應用邏輯。視圖組件也可以放到這個位置,他和監聽器其實是類似的,都能收納在服務提供器中。
比如,用服務提供器組織監聽器:
創建完提供器后,只需要簡單的在app/config/app.php配置中providers數組添加上它就好。
錯誤處理注意boot方法
記住,上例中我們使用boot的原因,register方法僅僅是用來將服務注冊到容器的方法。
如果應用中我們自定義了錯誤處理,別接管在“start”文件中,同樣,像事件監聽器一樣,最好還放在服務提供器中進行組織。提供器可以像這樣命名QuickBillErrorProvider,并在boot方法中講所有自定義的錯誤處理注冊進來,重申一下:我們要將這些代碼和我們的邏輯分離開來。最終,自定義的錯誤處理程序如下:
其他簡潔的方案
當然在只有一兩個錯誤處理方式的情況下,把他放到“start”文件也是一種簡潔的方式。
通常,類庫應該以PSR-0規范組織在我們的應用中。命令式代碼如事件監聽、錯誤處理、以及其他“注冊”類型的服務最好組織在服務提供器中。基于如上原則,我們就能決策出代碼的組織規律。有一點不要太猶豫,Laravel是為了讓工作方便于我們的業務,這也是Laravel的宗旨。尋找適合自己應用的結構,并分享給其他人。
如上,我們可以為所有自定義的服務提供器添加一個命名空間Providers并創建目錄組織起來:
// app // QuickBill // Billing // Extensions //Pagination -> Environment.php // Providers -> EventPusherServiceProvider.php // Repositories User.php Payment.php上例中,有兩個命名空間Extensions和Providers,自定義的服務放到Providers目錄下,對框架擴展的組件以Extensions命名空間的方式組織到同名目錄下。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/22980.html
摘要:劃下重點,服務容器是用于管理類的依賴和執行依賴注入的工具。類的實例化及其依賴的注入,完全由服務容器自動的去完成。 本文首發于 深入剖析 Laravel 服務容器,轉載請注明出處。喜歡的朋友不要吝嗇你們的贊同,謝謝。 之前在 深度挖掘 Laravel 生命周期 一文中,我們有去探究 Laravel 究竟是如何接收 HTTP 請求,又是如何生成響應并最終呈現給用戶的工作原理。 本章將帶領大...
摘要:然而,我們需要注意的是僅是軟件設計模式依賴注入的一種便利的實現形式。容器本身不是依賴注入的必要條件,在框架他只是讓其變得更加簡便。首先,讓我們探索下為什么依賴注入是有益的。繼續深入讓我們通過另一個示例來加深對依賴注入的理解。 聲明:本文并非博主原創,而是來自對《Laravel 4 From Apprentice to Artisan》閱讀的翻譯和理解,當然也不是原汁原味的翻譯,能保證9...
摘要:它是良好應用設計的大原則,包含單一責任原則開放封閉原則里氏替換原則接口分離原則依賴倒置原則讓我們通過代碼示例來深究下這五個原則。實探單一責任原則代表一個類有且僅有一個改變的原因,換言之,一個類的職責范疇是嚴謹明確的。 聲明:本文并非博主原創,而是來自對《Laravel 4 From Apprentice to Artisan》閱讀的翻譯和理解,當然也不是原汁原味的翻譯,能保證90%的原...
摘要:全書分三大部分共章第章介紹的基礎知識安裝和基本語法第章介紹的基本編程機器學習基礎及中常用的第三方庫函數,并介紹數據預處理的基本方法第章分別介紹常用的機器學習分析算法及深度學習等。每章都采用多個經典案例圖文并茂地介紹機器學習的原理和實現方法。 最近在學習Java和全棧開發,推薦一些有用的書籍 書架主要針對Java后端和全棧開發用的 書籍介紹 《Spring Boot 2.0企業級應用開發...
閱讀 2238·2021-11-15 11:39
閱讀 994·2021-09-26 09:55
閱讀 937·2021-09-04 16:48
閱讀 2846·2021-08-12 13:23
閱讀 927·2021-07-30 15:30
閱讀 2461·2019-08-29 14:16
閱讀 892·2019-08-26 10:15
閱讀 533·2019-08-23 18:40