Laravel程式架構設計動作類別的使用

不言
發布: 2023-03-30 16:00:02
原創
1948 人瀏覽過

這篇文章主要給大家介紹了關於Laravel程式架構設計思路之使用動作類的相關資料,文中透過範例程式碼介紹的非常詳細,對大家的學習或工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

前言

當我們談論到應用程式的架構的時候,常常會問到一個經典的問題,那就是「這段程式碼應該放在哪裡比較好」。因為 Laravel 是個相當靈活的框架,所以要回答這個問題其實沒那麼容易。我應該把我的業務邏輯寫在 Model 層,還是 Controller 層,還是其他地方?

當你的應用程式只有一個存取點,把業務邏輯寫在 Controller 層是可以的。但是現在更普遍的情況是,有很多接入點去呼叫相同的功能模組。

比如說,太多數的應用程式都有使用者註冊的功能,它的流程是呼叫一個控制器然後傳回一個註冊成功或失敗的視圖。假如這個應用程式還有行動端,那就很可能要提供一套針對行動端用戶註冊的 API ,因為它需要傳回的資料格式是 JSON 。而且利用 Laravel 的 artisan 指令來建立使用者也很常見,尤其是在專案前期的開發階段。

上面這兩段程式碼看起來沒有什麼問題的,但是,隨著業務邏輯的增加,就會顯得程式碼很冗餘。舉個例子,如果你需要新用戶註冊完之後,增加給用戶發送郵件通知的功能,你必須要再上面兩個控制器中都添加發送郵件的代碼。但如果要保持程式碼的簡潔優雅,我們可以把這些業務邏輯寫到其他地方。

對於「把業務邏輯程式碼寫到哪裡」的這個問題,你去任何論壇都可以得到一個普遍的答案,那就是 「使用一個 service 層,然後在 controller 層呼叫這個服務類別」。是的,沒錯,問題是我們該怎麼設計 service 類別?是建立一個 UserService 類別來實作所有跟使用者使用者相關的業務邏輯,然後把這個類別注入到需要用到的 Controller 層?還是還有其他方案?

避免神類的坑

首先,可以嘗試為特定的模型建立單一類,其中包含所有的程式碼。例如:

看起來很完美:我們可以任何控制器中申明或使用 create/delete 方法,並且得到我們想要的結果。但是,這種實作有什麼問題呢?那就是我們在解決問題的過程通常很少使用單一的模型 。

比如說,當我們為一個使用者建立了帳號的時候,也要同時給使用者單獨建立一個 blog 。如果按照目前的方式去實作這個流程,我們就必須建立一個 BlogService 類,然後將其相依性注入到 UserService 類別。

顯而易見,隨著應用程式的業務的成長,將會有數十到上百個service 類,其中的一些service 類別需要依賴5 到6 個其他service 類,最終的結果就是,出現程式碼的冗餘跟混亂的局面,而這個局面是我們想不惜一切代價去避免的。

介紹單一動作類別

那麼,如果不是用一個單一的服務類別加上幾個方法,我們決定把它分成幾個類別?以下是我最近每個專案都採用的方法,結果很不錯,推薦給大家。

首先,讓我們拋棄過於籠統和模糊的服務術語,來了解一下我們的新動作類,並定義它們是什麼以及它們可以做什麼。

  • 一個動作類,應該有一個能夠說明其功能的名字,例如:CreateOrder, ConfirmCheckout, DeleteProduct, AddProductToCart等。

  • 它應該有且只有一個公共方法,作為 API 。理想的情況下,應該是相同的方法名,像 handle() 或 execute() 。如果需要對我們的動作類別實作某種適配器模式,這是非常方便的。

  • 它必須對請求和回應不可知。它不處理請求,也不發送回應。這樣的職責應該由控制器來承擔。

  • 它可以依賴其它的動作類別。

  • 如果有任何事情阻止它執行和/或傳回期望的值,那麼它必須透過拋出一個Exception 來強制執行相關的業務邏輯,並且讓呼叫者(或Laravel的ExceptionHandler )來承擔如何呈現/回應異常的責任。

建立我們的 CreateUser 動作類別

#

現在,讓我們看看前面的例子,並用一個單動作類別來重構它,我們將命名為 CreateUser 。

你或許想知道當郵件地址已經被佔用時,該方法為什麼會拋出了例外。這不是請求驗證來保證的嗎?當然可以。然而,在動作類別內部來執行業務邏輯不是更好嗎?這樣使得邏輯變得易於理解和調試。

讓我們看看使用我們動作類別之後的控制器程式碼,如下:


#現在,無論我們做什麼修改,使用者註冊過程都會由API 和Web 版本處理,優雅整潔。

動作類別的巢狀

假如,我們需要一個動作類別將 1000 個使用者匯入我們的應用程式中。我們可以寫一個動作類,並且繼續使用上文的 CreateUser 類別:


#非常整潔,不是嗎?我們可以透過將其嵌入在 Collection::map() 方法中來重複使用 CreateUser 程式碼,然後傳回所有新建使用者的集合。當郵件被佔用的時候,我們可以透過回傳 Null Object 或在 Log 檔案中記錄一下,你應該已經想到了。

動作類別的裝飾

現在,假設我們想要在日誌中記錄每一個新註冊的使用者。我們可以將程式碼寫在動作類別內部,也可以使用裝飾者模式。

然後,我們可以使用Laravel 的IoC 容器將LogCreateUser 類別綁定到CreateUser 類,所有每當我們需要一個後者的實例時,前者都會注入進來:

AppServiceProvider.php

這使得使用設定或環境變數來控制日誌記錄功能的啟動或停用更為方便:


AppServiceProvider.php

#總結

使用這個方法似乎會需要很多的類。當然,用戶註冊只是一個簡單的例子,旨在保證程式碼的簡短清晰。一旦專案的複雜度開始成長,動作類別的真正的價值就越來越明顯,因為你清晰的知道程式碼所在及其界定。

使用單一動作類別的好處:

  • 小巧而單一的邏輯域能夠防止程式碼重複並提高程式碼的可重用性,保持穩定。

  • 易於針對各種場景進行獨立測試。

  • 富有意義的命名在大型專案中更容易閱讀。

  • 易於裝飾。

  • 整個專案的一致性:防止程式碼分佈在 Controllers、Models 等。

當然,這個方法是基於我過去幾年使用 Laravel 的一些經驗和我在一些專案中的實踐。這對我真的很有用,現在我什至在一些中小型專案中使用。

如果你有不同的方法,我非常期待讀一讀。

以上就是本文的全部內容,希望對大家的學習有所幫助,更多相關內容請關注PHP中文網!

相關推薦:

Laravel框架實作利用中間件進行操作日誌記錄功能

Laravel框架實作利用監聽器進行sql語句記錄功能

#

以上是Laravel程式架構設計動作類別的使用的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板