存儲庫設計模式神秘
核心要點
- 倉庫模式充當應用程序和數據源之間的中介層,允許構建解耦的架構,從而實現可擴展性,且無需硬編碼依賴關係。
- 此模式允許應用程序無需關注數據源的細節,而專注於接收和發送用於保存的數據。它通過一個公共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)

會話劫持可以通過以下步驟實現:1.獲取會話ID,2.使用會話ID,3.保持會話活躍。在PHP中防範會話劫持的方法包括:1.使用session_regenerate_id()函數重新生成會話ID,2.通過數據庫存儲會話數據,3.確保所有會話數據通過HTTPS傳輸。

PHP中有四種主要錯誤類型:1.Notice:最輕微,不會中斷程序,如訪問未定義變量;2.Warning:比Notice嚴重,不會終止程序,如包含不存在文件;3.FatalError:最嚴重,會終止程序,如調用不存在函數;4.ParseError:語法錯誤,會阻止程序執行,如忘記添加結束標籤。

PHP和Python各有優勢,選擇依據項目需求。 1.PHP適合web開發,尤其快速開發和維護網站。 2.Python適用於數據科學、機器學習和人工智能,語法簡潔,適合初學者。

HTTP請求方法包括GET、POST、PUT和DELETE,分別用於獲取、提交、更新和刪除資源。 1.GET方法用於獲取資源,適用於讀取操作。 2.POST方法用於提交數據,常用於創建新資源。 3.PUT方法用於更新資源,適用於完整更新。 4.DELETE方法用於刪除資源,適用於刪除操作。

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

PHP是一種廣泛應用於服務器端的腳本語言,特別適合web開發。 1.PHP可以嵌入HTML,處理HTTP請求和響應,支持多種數據庫。 2.PHP用於生成動態網頁內容,處理表單數據,訪問數據庫等,具有強大的社區支持和開源資源。 3.PHP是解釋型語言,執行過程包括詞法分析、語法分析、編譯和執行。 4.PHP可以與MySQL結合用於用戶註冊系統等高級應用。 5.調試PHP時,可使用error_reporting()和var_dump()等函數。 6.優化PHP代碼可通過緩存機制、優化數據庫查詢和使用內置函數。 7

箭頭函數在PHP7.4中引入,是短閉包的簡化形式。 1)它們使用=>運算符定義,省略function和use關鍵字。 2)箭頭函數自動捕獲當前作用域變量,無需use關鍵字。 3)它們常用於回調函數和短小計算,提高代碼簡潔性和可讀性。

PHP在電子商務、內容管理系統和API開發中廣泛應用。 1)電子商務:用於購物車功能和支付處理。 2)內容管理系統:用於動態內容生成和用戶管理。 3)API開發:用於RESTfulAPI開發和API安全性。通過性能優化和最佳實踐,PHP應用的效率和可維護性得以提升。
