核心要点
- 仓库模式充当应用程序和数据源之间的中介层,允许构建解耦的架构,从而实现可扩展性,且无需硬编码依赖关系。
- 此模式允许应用程序无需关注数据源的细节,而专注于接收和发送用于保存的数据。它通过一个公共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中文网其他相关文章!

绝对会话超时从会话创建时开始计时,闲置会话超时则从用户无操作时开始计时。绝对会话超时适用于需要严格控制会话生命周期的场景,如金融应用;闲置会话超时适合希望用户长时间保持会话活跃的应用,如社交媒体。

服务器会话失效可以通过以下步骤解决:1.检查服务器配置,确保会话设置正确。2.验证客户端cookies,确认浏览器支持并正确发送。3.检查会话存储服务,如Redis,确保其正常运行。4.审查应用代码,确保会话逻辑正确。通过这些步骤,可以有效诊断和修复会话问题,提升用户体验。

session_start()iscucialinphpformanagingusersessions.1)ItInitiateSanewsessionifnoneexists,2)resumesanexistingsessions,and3)setsasesessionCookieforContinuityActinuityAccontinuityAcconActInityAcconActInityAcconAccRequests,EnablingApplicationsApplicationsLikeUseAppericationLikeUseAthenticationalticationaltication and PersersonalizedContentent。

设置httponly标志对会话cookie至关重要,因为它能有效防止XSS攻击,保护用户会话信息。具体来说,1)httponly标志阻止JavaScript访问cookie,2)在PHP和Flask中可以通过setcookie和make_response设置该标志,3)尽管不能防范所有攻击,但应作为整体安全策略的一部分。

phpsessions solvathepromblymaintainingStateAcrossMultipleHttpRequestsbyStoringDataTaNthEserVerAndAssociatingItwithaIniquesestionId.1)他们储存了AtoredAtaserver side,通常是Infilesordatabases,InseasessessionIdStoreDistordStoredStoredStoredStoredStoredStoredStoreDoreToreTeReTrestaa.2)

tostartaphpsession,usesesses_start()attheScript'Sbeginning.1)placeitbeforeanyOutputtosetThesessionCookie.2)useSessionsforuserDatalikeloginstatusorshoppingcarts.3)regenerateSessiveIdStopreventFentfixationAttacks.s.4)考虑使用AttActAcks.s.s.4)

会话再生是指在用户进行敏感操作时生成新会话ID并使旧ID失效,以防会话固定攻击。实现步骤包括:1.检测敏感操作,2.生成新会话ID,3.销毁旧会话ID,4.更新用户端会话信息。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3 Linux新版
SublimeText3 Linux最新版

VSCode Windows 64位 下载
微软推出的免费、功能强大的一款IDE编辑器

适用于 Eclipse 的 SAP NetWeaver 服务器适配器
将Eclipse与SAP NetWeaver应用服务器集成。

mPDF
mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),