首页 后端开发 php教程 存储库设计模式神秘

存储库设计模式神秘

Feb 21, 2025 am 08:54 AM

Repository Design Pattern Demystified

核心要点

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

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

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

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

热门话题

Java教程
1657
14
CakePHP 教程
1415
52
Laravel 教程
1309
25
PHP教程
1257
29
C# 教程
1231
24
会话如何劫持工作,如何在PHP中减轻它? 会话如何劫持工作,如何在PHP中减轻它? Apr 06, 2025 am 12:02 AM

会话劫持可以通过以下步骤实现:1.获取会话ID,2.使用会话ID,3.保持会话活跃。在PHP中防范会话劫持的方法包括:1.使用session_regenerate_id()函数重新生成会话ID,2.通过数据库存储会话数据,3.确保所有会话数据通过HTTPS传输。

说明PHP中的不同错误类型(注意,警告,致命错误,解析错误)。 说明PHP中的不同错误类型(注意,警告,致命错误,解析错误)。 Apr 08, 2025 am 12:03 AM

PHP中有四种主要错误类型:1.Notice:最轻微,不会中断程序,如访问未定义变量;2.Warning:比Notice严重,不会终止程序,如包含不存在文件;3.FatalError:最严重,会终止程序,如调用不存在函数;4.ParseError:语法错误,会阻止程序执行,如忘记添加结束标签。

PHP和Python:比较两种流行的编程语言 PHP和Python:比较两种流行的编程语言 Apr 14, 2025 am 12:13 AM

PHP和Python各有优势,选择依据项目需求。1.PHP适合web开发,尤其快速开发和维护网站。2.Python适用于数据科学、机器学习和人工智能,语法简洁,适合初学者。

什么是HTTP请求方法(获取,发布,放置,删除等),何时应该使用? 什么是HTTP请求方法(获取,发布,放置,删除等),何时应该使用? Apr 09, 2025 am 12:09 AM

HTTP请求方法包括GET、POST、PUT和DELETE,分别用于获取、提交、更新和删除资源。1.GET方法用于获取资源,适用于读取操作。2.POST方法用于提交数据,常用于创建新资源。3.PUT方法用于更新资源,适用于完整更新。4.DELETE方法用于删除资源,适用于删除操作。

说明PHP中的安全密码散列(例如,password_hash,password_verify)。为什么不使用MD5或SHA1? 说明PHP中的安全密码散列(例如,password_hash,password_verify)。为什么不使用MD5或SHA1? Apr 17, 2025 am 12:06 AM

在PHP中,应使用password_hash和password_verify函数实现安全的密码哈希处理,不应使用MD5或SHA1。1)password_hash生成包含盐值的哈希,增强安全性。2)password_verify验证密码,通过比较哈希值确保安全。3)MD5和SHA1易受攻击且缺乏盐值,不适合现代密码安全。

PHP:网络开发的关键语言 PHP:网络开发的关键语言 Apr 13, 2025 am 12:08 AM

PHP是一种广泛应用于服务器端的脚本语言,特别适合web开发。1.PHP可以嵌入HTML,处理HTTP请求和响应,支持多种数据库。2.PHP用于生成动态网页内容,处理表单数据,访问数据库等,具有强大的社区支持和开源资源。3.PHP是解释型语言,执行过程包括词法分析、语法分析、编译和执行。4.PHP可以与MySQL结合用于用户注册系统等高级应用。5.调试PHP时,可使用error_reporting()和var_dump()等函数。6.优化PHP代码可通过缓存机制、优化数据库查询和使用内置函数。7

PHP行动:现实世界中的示例和应用程序 PHP行动:现实世界中的示例和应用程序 Apr 14, 2025 am 12:19 AM

PHP在电子商务、内容管理系统和API开发中广泛应用。1)电子商务:用于购物车功能和支付处理。2)内容管理系统:用于动态内容生成和用户管理。3)API开发:用于RESTfulAPI开发和API安全性。通过性能优化和最佳实践,PHP应用的效率和可维护性得以提升。

解释PHP 7.4中引入的箭头功能(短闭合)。 解释PHP 7.4中引入的箭头功能(短闭合)。 Apr 06, 2025 am 12:01 AM

箭头函数在PHP7.4中引入,是短闭包的简化形式。1)它们使用=>运算符定义,省略function和use关键字。2)箭头函数自动捕获当前作用域变量,无需use关键字。3)它们常用于回调函数和短小计算,提高代码简洁性和可读性。

See all articles