溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

web開發(fā)中大型項(xiàng)目該怎么分層架構(gòu)

發(fā)布時(shí)間:2021-11-06 11:25:53 來(lái)源:億速云 閱讀:250 作者:iii 欄目:web開發(fā)

這篇文章主要講解了“web開發(fā)中大型項(xiàng)目該怎么分層架構(gòu)”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來(lái)研究和學(xué)習(xí)“web開發(fā)中大型項(xiàng)目該怎么分層架構(gòu)”吧!

再見,模型

刪掉你的 models 目錄了嗎?還沒(méi)刪就趕緊刪了!我們將要在 app 目錄下創(chuàng)建一個(gè)新的目錄,目錄名就以我們這個(gè)應(yīng)用的名字來(lái)命名,比如  QuickBill。我們將繼續(xù)使用在前面章節(jié)中編寫的那些接口和類。

>注意使用場(chǎng)景:記住,如果你在構(gòu)建一個(gè)很小的 Laravel 應(yīng)用,那在models 目錄下寫幾個(gè) Eloquent  模型其實(shí)挺合適的。但在本章節(jié),我們主要關(guān)注如何開發(fā)適用于分層架構(gòu)的大型復(fù)雜項(xiàng)目。

所以,我們現(xiàn)在有了個(gè) app/QuickBill 目錄,它和應(yīng)用目錄下的其他目錄如 Http 還有 Console 都是平級(jí)的。在 QuickBill  目錄下我們還可以創(chuàng)建幾個(gè)其他目錄,例如 Repositories 和 Billing 目錄。目錄都創(chuàng)建好以后,別忘了在 composer.json 文件里通過(guò)  PSR-4 自動(dòng)載入機(jī)制將它們注冊(cè)到 QuickBill 命名空間下:

"autoload": {  "classmap": [  "database/seeds",  "database/factories"  ],  "psr-4": {  "App\\": "app/",  "QuickBill\\": "app/QuickBill"  } },

現(xiàn)在,我們把所有 Eloquent 模型類都放到 QuickBill 目錄下面。這樣我們就能很方便的以  QuickBill\User、QuickBill\Payment 這種方式來(lái)使用它們。Repositories 目錄下包含 PaymentRepository  和UserRepository 這種倉(cāng)庫(kù)類,倉(cāng)庫(kù)類里面包含了所有對(duì)數(shù)據(jù)的訪問(wèn)功能,比如 getRecentPayments 和  getRichestUser。Billing 目錄包含了調(diào)用第三方支付服務(wù)(如 Stripe 和  Balanced)的類和接口。整個(gè)目錄結(jié)構(gòu)現(xiàn)在應(yīng)該類似這樣:

// app  // QuickBill  // Repositories  -> UserRepository.php  -> PaymentRepository.php  // Billing  -> BillerInterface.php  -> StripeBiller.php  // Notifications  -> BillingNotifierInterface.php  -> SmsBillingNotifier.php  User.php  Payment.php

數(shù)據(jù)驗(yàn)證放在哪?在哪兒進(jìn)行數(shù)據(jù)驗(yàn)證常常困擾著開發(fā)人員??梢钥紤]將數(shù)據(jù)驗(yàn)證方法寫進(jìn)你的「實(shí)體」類里面(例如 User.php 和  Payment.php)。方法名可以設(shè)置為 validForCreation 或 hasValidDomain?;蛘吣阋部梢詫iT創(chuàng)建一個(gè)驗(yàn)證器類  UserValidator,放到 Validation 命名空間下,然后將這個(gè)驗(yàn)證器類注入到你的 Repository  類里面。兩種方式你都可以試試,看哪個(gè)你更喜歡!當(dāng)然在 Laravel 5.* 中,你不需要自己創(chuàng)建驗(yàn)證器類了,通過(guò) Laravel  自帶的驗(yàn)證器類就可以滿足你的所有需求。

擺脫了 models  目錄的束縛后,你通常就能克服實(shí)現(xiàn)好的架構(gòu)設(shè)計(jì)的心理障礙,也就能夠構(gòu)建一個(gè)更合適應(yīng)用的目錄結(jié)構(gòu)。當(dāng)然,你構(gòu)建的每一個(gè)應(yīng)用程序都會(huì)有一定的相似之處,因?yàn)椴还芏鄰?fù)雜的應(yīng)用程序都需要一個(gè)數(shù)據(jù)訪問(wèn)層(Repository),以及一些外部服務(wù)層等等。

別害怕目錄:不要懼怕創(chuàng)建更多目錄來(lái)組織管理應(yīng)用。將整個(gè)應(yīng)用切割成多個(gè)細(xì)分的功能組件總是必要的,每一個(gè)功能組件都專注于某一項(xiàng)職責(zé)。跳出「模型」的框框來(lái)思考總是有幫助的。例如,我們之前就討論過(guò),你可以創(chuàng)建一個(gè)  Repositories 目錄來(lái)存放所有的數(shù)據(jù)訪問(wèn)類。

核心思想就是分層

你可能已經(jīng)注意到,優(yōu)化應(yīng)用目錄結(jié)構(gòu)的關(guān)鍵就是對(duì)不同組件的責(zé)任進(jìn)行劃分,或者說(shuō)為不同的職責(zé)創(chuàng)建不同的層。控制器只負(fù)責(zé)接收和響應(yīng) HTTP  請(qǐng)求,然后調(diào)用合適的業(yè)務(wù)邏輯層的類。你的業(yè)務(wù)邏輯/領(lǐng)域邏輯層才是應(yīng)用最核心的部分,其中包含了讀取數(shù)據(jù),驗(yàn)證數(shù)據(jù),執(zhí)行支付,發(fā)送電子郵件,還有程序里所有其他功能的代碼。事實(shí)上,你的領(lǐng)域邏輯層不需要知道任何關(guān)于「Web」的事情!Web  層僅僅是一種訪問(wèn)應(yīng)用程序的傳輸機(jī)制,關(guān)于 Web 和 HTTP  請(qǐng)求的一切不應(yīng)該超出路由和控制器層的范圍。做出好的架構(gòu)設(shè)計(jì)的確很有挑戰(zhàn)性,但好的架構(gòu)設(shè)計(jì)也會(huì)帶來(lái)可維護(hù)的、更加清晰的代碼。

舉個(gè)例子,與其在業(yè)務(wù)邏輯類里面直接獲取 Web 請(qǐng)求,不如把 Web  請(qǐng)求通過(guò)控制器傳遞給業(yè)務(wù)邏輯類。這個(gè)簡(jiǎn)單的改動(dòng)會(huì)將你的業(yè)務(wù)邏輯類和「Web」層解耦,并且不必?fù)?dān)心怎么去模擬 Web 請(qǐng)求,就可以輕松測(cè)試業(yè)務(wù)邏輯類:

class BillingController extends BaseController {    public function __construct(BillerInterface $biller)  {  $this->biller = $biller;  }    public function postCharge(Request $request)  {  $this->biller->chargeAccount(Auth::user(), $request->input('amount'));  return view('charge.success');  }   }

現(xiàn)在 chargeAccount 方法更容易測(cè)試了,由于我們不再需要在 BillerInterface 實(shí)現(xiàn)類中使用 User 和 Request  類,只需將用戶和金額傳遞到該方法即可。

編寫可維護(hù)性應(yīng)用程序的關(guān)鍵之一,就是職責(zé)分離。要時(shí)常檢查一個(gè)類是否管得太寬,知道一些它不該知道的。你要常常問(wèn)自己「這個(gè)類是否需要關(guān)心X?」如果答案是否定的,那么就要把這塊邏輯提取出來(lái)放到另一個(gè)類里面,然后用依賴注入的方式將其注入進(jìn)來(lái)。

如何判斷一個(gè)類是否管得太寬?一個(gè)有用的方法就是檢查你為什么要改這塊代碼。舉個(gè)例子,當(dāng)我們想調(diào)整通知邏輯的時(shí)候,是否需要修改 Biller  的實(shí)現(xiàn)代碼?當(dāng)然不需要,Biller  實(shí)現(xiàn)只關(guān)注支付,它與通知邏輯應(yīng)當(dāng)僅通過(guò)契約來(lái)進(jìn)行交互。在處理代碼時(shí)使用這種思路,可以幫助你快速找出應(yīng)用中需要改進(jìn)的地方。

東西都放哪兒?

當(dāng)通過(guò) Laravel  開發(fā)應(yīng)用時(shí),你可能會(huì)困惑于應(yīng)該把各種「東西」放在哪里。例如,輔助函數(shù)要放在哪里?事件監(jiān)聽器要放在哪里?視圖組件要放在哪里?答案可能出乎你的意料 ——  「隨便,放哪兒都行!」Laravel  并沒(méi)有很多關(guān)于這方面的文件系統(tǒng)上的約定。不過(guò),這個(gè)答案的確不能讓人滿意,所以下面我們就這個(gè)問(wèn)題展開討論,一起探討這些「東西」究竟可以放在哪里。

輔助函數(shù)

我們可以在 app 目錄下創(chuàng)建一個(gè) helpers.php  文件,然后將自定義的輔助函數(shù)都放到這個(gè)文件中。當(dāng)然,由于這個(gè)文件里面包含的不是類,不適合通過(guò)命名空間引用其中的函數(shù),需要在 composer.json  中全局注冊(cè)它:

"autoload": {  ...  "files": [  "app/helpers.php"  ] },

然后運(yùn)行 composer dump-auto 重新注冊(cè)自動(dòng)加載映射關(guān)系。然后就可以在應(yīng)用中使用 app/helpers.php  中定義的輔助函數(shù)了。

事件監(jiān)聽器

事件監(jiān)聽器當(dāng)然不該放到 routes.php 文件里面,所以我們要找另外的地方來(lái)存放。事實(shí)上,在 Laravel 5.* 中,當(dāng)我們通過(guò) php  artisan make:listener 命令創(chuàng)建時(shí)間監(jiān)聽器時(shí),系統(tǒng)會(huì)自動(dòng)在 app 目錄下創(chuàng)建 Listeners  子目錄,并將生成的監(jiān)聽器類放到該目錄下。所以我們對(duì)于自定義的事件監(jiān)聽器類,放到該目錄下即可。

錯(cuò)誤處理器

在 Laravel 5.* 版本中,默認(rèn)情況下所有的異常都是通過(guò) App\Exceptions\Handler  來(lái)處理的,你也可以通過(guò)自定義的異常類來(lái)處理,自定義異常類可以放到 app/Exceptions 目錄下。

其他

通常,只要遵循 PSR-4  規(guī)范就可以在應(yīng)用目錄結(jié)構(gòu)中保持類的整齊。結(jié)合你目前為止學(xué)習(xí)到的知識(shí),對(duì)于什么代碼要放在什么地方這個(gè)問(wèn)題,應(yīng)當(dāng)可以給出一個(gè)有理有據(jù)的答案了。但永遠(yuǎn)不要拒絕試驗(yàn)。Laravel  的美妙之處就是你可以做出最適合你自己應(yīng)用的約定。去探索和發(fā)現(xiàn)最適合你自己應(yīng)用的結(jié)構(gòu)吧,別忘了和他人分享你的見解!

例如,你可能受到我們之前例子的啟發(fā),在 QuickBill 中創(chuàng)建一個(gè) Providers 目錄來(lái)存放所有你自定義的服務(wù)提供者,目錄結(jié)構(gòu)類似這樣:

// app  // QuickBill  // Billing  // Extensions  //Pagination  -> Environment.php  // Providers  -> EventPusherServiceProvider.php  // Repositories  User.php  Payment.php

注意上面的例子,我們有 Providers 和 Extensions 兩個(gè)命名空間。所有你自定義的服務(wù)提供者都可以放到 Providers 命名空間下,而  Extensions 命名空間可以用來(lái)存放你對(duì)框架核心進(jìn)行擴(kuò)展的類。

感謝各位的閱讀,以上就是“web開發(fā)中大型項(xiàng)目該怎么分層架構(gòu)”的內(nèi)容了,經(jīng)過(guò)本文的學(xué)習(xí)后,相信大家對(duì)web開發(fā)中大型項(xiàng)目該怎么分層架構(gòu)這一問(wèn)題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

web
AI