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