存儲庫設計模式神秘
核心要點
- 倉庫模式充當應用程序和數據源之間的中介層,允許構建解耦的架構,從而實現可擴展性,且無需硬編碼依賴關係。
- 此模式允許應用程序無需關注數據源的細節,而專注於接收和發送用於保存的數據。它通過一個公共API(接口)實現這一點,所有使用者都通過該接口與數據源進行通信。
- 雖然倉庫模式提供了關注點分離和易於單元測試等好處,但它也增加了一層抽象,這可能會使小型應用程序變得複雜。
- 實現倉庫模式需要依賴注入,這允許將數據倉庫綁定到倉庫接口。這避免了硬編碼耦合,並促進了面向接口編程。
什麼是倉庫模式?
簡單來說,它是應用程序和數據源之間中介層的一種實現。雙方都不需要了解對方即可執行各自的任務,這使得我們可以擁有一個解耦的架構,從而有助於在大型應用中進行擴展,而無需硬編碼依賴關係。
為什麼你應該關注它?
讓我們用一個例子來理解這一點。假設我們正在構建一個在線商店,銷售橙味糖果。這是一個小型商店,它保留本地庫存,所以我們不需要任何花哨的東西。店面應用程序可以只連接到數據庫,並根據現有的庫存量在線接單。由於商店只有一個供應倉庫並且運營區域有限,這將運行良好。但是,如果這家商店想要擴大其運營區域會發生什麼?商店可能想要擴展到另一個城市或全國各地,而擁有一個中央庫存系統將非常麻煩。
如果我們仍然使用數據模型,那麼我們的應用程序將是某種程度上緊密耦合的。店面應用程序需要知道它必須與之交互的每個數據源,這是一個糟糕的應用程序設計。店面應用程序的工作是允許客戶訂購糖果,應用程序不應該關心數據源,它不應該跟踪所有不同的數據源。這就是數據倉庫發揮作用的地方。根據倉庫模式,一個公共API通過接口公開,每個使用者(在本例中是我們的店面應用程序)都使用該API與數據源進行通信。使用哪個數據源或如何連接到它,這些都不關應用程序的事。應用程序只關心它獲得的數據和它發送以保存的數據。
一旦實現了倉庫模式,就可以為每個數據源創建倉庫。店面應用程序不再需要跟踪任何數據源,它只需使用倉庫API來獲取所需的數據。
它是萬能藥嗎?
不,它不是。像每個設計模式一樣,它有其優缺點。
優點:
- 關注點分離;應用程序無需了解或跟踪任何或所有數據源。
- 允許輕鬆進行單元測試,因為倉庫綁定到在運行時注入類的接口。
- DRY(不要重複自己)設計,從數據源查詢和獲取數據的代碼不會重複。
缺點:
- 添加了另一層抽象,增加了一定程度的複雜性,使其對於小型應用程序來說過於復雜。
如何操作?
讓我們來看一個簡單的代碼示例。我將在示例中使用 Laravel 來利用其出色的依賴注入功能。如果您使用任何現代 PHP 框架,那麼它應該已經具有依賴注入/IoC 容器。實現倉庫模式需要依賴注入,因為如果沒有它,您將無法將數據倉庫綁定到倉庫接口,而整個想法是面向接口編程以避免硬編碼耦合。如果您沒有使用任何框架或您選擇的框架沒有 IoC 容器,那麼您可以使用現成的 IoC 容器(請參閱腳註)。
讓我們開始吧。首先,我們在 Composer 中設置我們的命名空間和自動加載。打開 composer.json 並為我們的命名空間添加 psr-4 自動加載(在 autoload 節點中,緊跟在 classmap 之後)。
"autoload": { "classmap": [ "app/commands", "app/controllers", "app/models", "app/database/migrations", "app/database/seeds", "app/tests/TestCase.php" ], "psr-4": { "RocketCandy\": "app/RocketCandy" } },
保存後,在終端中執行 composer dump-autoload -o
以註冊新命名空間的自動加載。在 app/RocketCandy/Repositories/OrangeCandyRepository/
中創建 OrangeCandyRepository.php
。這將是我們的倉庫接口。
<?php namespace RocketCandy\Repositories\OrangeCandyRepository; interface OrangeCandyRepository { public function get_list( $limit = 0, $skip = 0 ); public function get_detail( $candy_id = 0 ); }
現在我們有了接口,我們可以創建一個倉庫。在 app/RocketCandy/Repositories/OrangeCandyRepository/
中創建 CityAOrangeCandyRepository.php
。
<?php namespace RocketCandy\Repositories\OrangeCandyRepository; class CityAOrangeCandyRepository implements OrangeCandyRepository { public function get_list( $limit = 0, $skip = 0 ) { // 查询数据源并获取糖果列表 } public function get_detail( $candy_id = 0 ) { // 查询数据源并获取糖果详情 } }
為了將 CityAOrangeCandyRepository
倉庫綁定到 OrangeCandyRepository
接口,我們將利用 Laravel 的 IoC 容器。打開 app/start/global.php
並將以下內容添加到文件的末尾。
//OrangeCandyRepository App::bind( 'RocketCandy\Repositories\OrangeCandyRepository\OrangeCandyRepository', 'RocketCandy\Repositories\OrangeCandyRepository\CityAOrangeCandyRepository' );
注意:我只在 global.php
中放置了 IoC 綁定以進行演示。理想情況下,這些應該放在它們自己的單獨文件中,您可以在其中放置所有IoC 綁定,然後在此處的global.php
中加載該文件,或者您可以創建服務提供程序來註冊每個IoC綁定。您可以在這裡閱讀更多信息。
現在我們可以通過接口使用倉庫了。在位於 app/controllers/
中的 CandyListingController.php
中。
"autoload": { "classmap": [ "app/commands", "app/controllers", "app/models", "app/database/migrations", "app/database/seeds", "app/tests/TestCase.php" ], "psr-4": { "RocketCandy\": "app/RocketCandy" } },
在這裡,我們將 OrangeCandyRepository
接口注入到我們的控制器中,並將它的對象引用存儲在一個類變量中,該變量現在可以被控制器中的任何函數用來查詢數據。由於我們將 OrangeCandyRepository
接口綁定到 CityAOrangeCandyRepository
倉庫,它將就像我們直接使用 CityAOrangeCandyRepository
倉庫一樣。
因此,現在,數據源的類型和種類是 CityAOrangeCandyRepository
的唯一關注點。我們的應用程序只知道 OrangeCandyRepository
接口及其公開的 API,每個實現它的倉庫都必須遵守該 API。倉庫在運行時從IoC 容器中解析,這意味著可以根據需要設置接口倉庫綁定,接口可以綁定到任何數據倉庫,而我們的應用程序無需關心數據源的變化,數據源現在可以是數據庫、 Web 服務或跨維度超數據管道。
並非所有情況都適用
正如我在倉庫模式的缺點中提到的那樣,它會增加應用程序的一定複雜性。因此,如果您正在製作一個小型應用程序,並且您沒有看到它會發展到大型應用的程度(可能需要調用多個數據源),那麼最好不要實現它,而堅持使用舊式數據模型。了解某事物與了解何時使用該事物是不同的。這是一個非常方便的設計模式,它在創建應用程序以及必須維護或擴展(或縮減)應用程序時可以節省很多麻煩,但它並非適用於所有應用程序的萬能藥。
我使用了 Laravel 特定的代碼來演示上面的實現,但是它對於任何不錯的 IoC 容器來說都相當簡單且相似。有問題?請在下面的評論中提出。
腳註:
-
以下是一些您可以使用的 IoC 容器庫,如果您的框架沒有或您沒有使用框架:
- OrnoDi
- Ray.Di
- Auryn
- Dice
- Bucket
- Ding
-
建議閱讀:
- Domain Driven Design Quickly
- Domain-Driven Design by Eric Evans
關於倉庫模式的常見問題
(此部分內容與原文內容高度重合,為了避免重複,此處省略。原文中的常見問題解答部分已包含了對倉庫模式的全面解釋。)
以上是存儲庫設計模式神秘的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

在PHP中,應使用password_hash和password_verify函數實現安全的密碼哈希處理,不應使用MD5或SHA1。1)password_hash生成包含鹽值的哈希,增強安全性。 2)password_verify驗證密碼,通過比較哈希值確保安全。 3)MD5和SHA1易受攻擊且缺乏鹽值,不適合現代密碼安全。

PHP類型提示提升代碼質量和可讀性。 1)標量類型提示:自PHP7.0起,允許在函數參數中指定基本數據類型,如int、float等。 2)返回類型提示:確保函數返回值類型的一致性。 3)聯合類型提示:自PHP8.0起,允許在函數參數或返回值中指定多個類型。 4)可空類型提示:允許包含null值,處理可能返回空值的函數。

PHP主要是過程式編程,但也支持面向對象編程(OOP);Python支持多種範式,包括OOP、函數式和過程式編程。 PHP適合web開發,Python適用於多種應用,如數據分析和機器學習。

PHP適合網頁開發和快速原型開發,Python適用於數據科學和機器學習。 1.PHP用於動態網頁開發,語法簡單,適合快速開發。 2.Python語法簡潔,適用於多領域,庫生態系統強大。

PHP起源於1994年,由RasmusLerdorf開發,最初用於跟踪網站訪問者,逐漸演變為服務器端腳本語言,廣泛應用於網頁開發。 Python由GuidovanRossum於1980年代末開發,1991年首次發布,強調代碼可讀性和簡潔性,適用於科學計算、數據分析等領域。

PHP的核心優勢包括易於學習、強大的web開發支持、豐富的庫和框架、高性能和可擴展性、跨平台兼容性以及成本效益高。 1)易於學習和使用,適合初學者;2)與web服務器集成好,支持多種數據庫;3)擁有如Laravel等強大框架;4)通過優化可實現高性能;5)支持多種操作系統;6)開源,降低開發成本。

PHP在現代化進程中仍然重要,因為它支持大量網站和應用,並通過框架適應開發需求。 1.PHP7提升了性能並引入了新功能。 2.現代框架如Laravel、Symfony和CodeIgniter簡化開發,提高代碼質量。 3.性能優化和最佳實踐進一步提升應用效率。

PHPhassignificantlyimpactedwebdevelopmentandextendsbeyondit.1)ItpowersmajorplatformslikeWordPressandexcelsindatabaseinteractions.2)PHP'sadaptabilityallowsittoscaleforlargeapplicationsusingframeworkslikeLaravel.3)Beyondweb,PHPisusedincommand-linescrip
