下面由Laravel教程欄目帶大家推薦介紹關于Laravel存儲庫模式(Repository),希望對大家有所幫助!

- 1. Laravel 中的存儲庫模式(Repository)
- 2. 為什么要在 Laravel 中使用存儲庫模式(Repository)?
在大多數 web 應用程序中,訪問數據庫占了代碼庫的很大一部分。為了避免在我們應用程序邏輯上摻雜 SQL 查詢,我們依賴抽象,它隱藏了 PHP 方法背后的數據訪問機制。
有幾種模式可以結構化數據訪問,“Active Record” 和 “Repository” 是最著名的兩種。在這篇博文中,我將在 Laravel 框架 的背景下具體解釋它們。關于使用 Repository 模式的優點和缺點的討論將在單獨的博客文章中進行。
活動記錄
默認情況下,Laravel 使用 Active Record 模式。每個 Laravel 程序員都直觀地使用它,因為它是在抽象的 Model 基類中實現的,而模型通常從它繼承而來。讓我們來看一個例子:
use IlluminateDatabaseEloquentModel; /** * @property int $id * @property string $first_name * @property string $last_name */ class Person extends Model { } // --- 使用: $person = new Person(); $person->first_name = 'Jack'; $person->last_name = 'Smith'; $person->save();
當然,您可以讀寫您在 Person 上創建的屬性。 但是要保存模型,您也可以 直接在模型上調用方法。 不需要另一個對象——模型已經提供了訪問相應數據庫表的所有方法。
這意味著,域模型將您的自定義屬性和方法與同一類中的所有數據訪問方法相結合。 第二部分是通過繼承 Model 來實現的。
要點:
- Active Record 結合 域模型與數據訪問功能。
- Laravel 使用 Active Record 模式并通過
Model類實現它。
Repository
Repository 模式是 Active Record 模式的替代方案。它還提供了處理數據訪問的抽象。但更廣泛地說,它可以被視為域對象的概念性存儲庫或集合。
與活動記錄模式相反,存儲模式將數據庫訪問與域模型分離。它提供了一個高級接口,你可以在其中創建、讀取、更新和刪除域模型,而不必考慮實際的底層數據存儲。
底層的存儲庫可以通過構建和執行 SQL 查詢訪問數據庫,通過 REST API 訪問遠程系統,或者僅僅管理包含所有域模型的內存數據結構。這對測試很有用。存儲庫模式關鍵部分是它為其余代碼提供的高級接口。
要點:
- 存儲庫表示域對象的概念集合。
- 它只負責用高級接口封裝數據訪問。
- Laravel 沒有提供實現存儲庫模式的特定幫助程序
在 Laravel 中實現 Repository 模式時,我主要看到兩種變體。
變體1:特定方法
在第一個變體中,存儲庫方法是重點和特定的。名稱解釋了調用者獲得的內容,用于參數化底層查詢的選項是有限的。
class InvoiceRepository { public function findAllOverdue(Carbon $since, int $limit = 10): Collection { return Invoice::where('overdue_since', '>=', $since) ->limit($limit) ->orderBy('overdue_since') ->get(); } public function findInvoicedToCompany(string $companyId): Collection { return Invoice::where('company_id', $companyId) ->orderByDesc('created_at') ->get(); } }
這種方法的優勢在于方法的表現力。閱讀代碼時,很清楚從方法中期望什么以及如何調用它們。這會導致更少的錯誤。 Repository 方法很容易測試,因為參數有限。
這種方法的一個缺點是,最終可能會在存儲庫中使用大量的方法。由于方法無法輕松重用,因此必須為新用例添加其他方法。
要點:
- 存儲模式可以通過提供特定方法的類來實現
- 每個方法包裝一個查詢,只公開必要的參數
- 優點: 可讀性和可測試性
- 缺點: 缺乏靈活性和較低的可重用性
變式2: 一般方法
另一方面的方法是提供一般的方法。這導致了方法的減少。但是這些方法有一個很大的 API 曲面,因為每個方法都可以使用不同的參數組合來調用。
其中的關鍵問題是參數表示。這種表示應該引導調用方理解方法簽名并避免無效的輸入。為此,您可以引入一個特殊的類,例如使用 Query Object 模式。
但是我在實踐中經常看到的是標量參數和 PHP 數組的混合。調用方可以傳遞完全無效的輸入,僅類型數據并不能說明要傳遞什么。但是如果使用得當,這種輕量級的方法可以避免更繁瑣的抽象。
class InvoiceRepository { public function find(array $conditions, string $sortBy = 'id', string $sortOrder = 'asc', int $limit = 10): Collection { return Invoice::where($conditions) ->orderBy($sortBy, $sortOrder) ->limit($limit) ->get(); } } // --- 使用: $repo = new InvoiceRepository(); $repo->find(['overdue_since', '>=', $since], 'overdue_since', 'asc'); $repo->find(['company_id', '=', $companyId], 'created_at', 'asc', 100);
這種方法減輕了第一種方法的問題:你可以得到更少的 Repository 方法,這些方法更靈活,并且可以更頻繁地重用。
從消極的方面看,Repository 變得更加難以測試,因為有
站長資訊網