」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > Laravel 領域驅動設計 (DDD) 簡單指南

Laravel 領域驅動設計 (DDD) 簡單指南

發佈於2024-11-08
瀏覽:492

A Simple Guide to Domain-Driven Design (DDD) in Laravel

您是否曾感觉到,随着 Laravel 项目的发展,事情开始变得有点失控?控制器变得臃肿,模型开始做太多事情,突然之间,你的代码库就像你几个月来一直想组织的抽屉一样。这就是 领域驱动设计 (DDD) 可以介入并让您的生活更轻松的地方。

DDD 是一种设计应用程序的方法,使其结构与您在现实世界中解决的问题紧密结合。随着项目的发展,它有助于使您的代码更清晰、更具可扩展性并且更易于管理。

在本指南中,我们将引导您了解 Laravel 中的 DDD 基础知识,解释如何实现它,并向您展示一些现实世界的示例。

目录

  1. 什么是领域驱动设计(DDD)?
  2. 为什么在 Laravel 中使用 DDD?
  3. DDD 的组成部分
    • 实体
    • 值对象
    • 存储库
    • 服务
  4. 在 Laravel 中实现 DDD
    • 示例1:构建订单管理系统
    • 示例 2:管理用户订阅
  5. Laravel 中 DDD 的优缺点
  6. 最后的想法

什么是领域驱动设计(DDD)?

在深入了解 Laravel 细节之前,让我们先介绍一下 领域驱动设计 (DDD) 的全部内容。 DDD 是一种通过关注业务领域(您的软件正在解决的核心问题)来组织应用程序代码的方法。

您不是围绕控制器或模型等技术概念构建代码,而是围绕现实世界概念构建代码。这可能是订单、产品或客户等内容,具体取决于您的应用程序的用途。

简而言之,DDD 可帮助您构建反映现实世界流程的应用程序,使代码更易于理解和维护,尤其是随着代码的增长。

为什么在 Laravel 中使用 DDD?

如果您熟悉 Laravel 默认使用的 MVC(模型-视图-控制器)模式,您就会知道它对于大多数应用程序都很有效。但随着应用程序的扩展,MVC 模式可能会导致混乱的相互依赖的代码。 领域驱动设计通过使您的应用程序更容易扩展和维护来解决这个问题。

DDD 还将业务逻辑基础设施代码分开。这意味着您的应用程序逻辑不会与数据库或 API 之类的东西绑定,从而使以后更容易更换技术。

DDD 的组成部分

要了解 DDD 的工作原理,您需要了解其关键组件。让我们来分解一下:

实体

实体是您的域中具有独特身份的对象。例如,订单是一个实体,因为每个订单都是唯一的。

// app/Domain/Order/Order.php
class Order {
    private $id;
    private $status;

    public function __construct($id, $status) {
        $this->id = $id;
        $this->status = $status;
    }

    // Getter and other business logic
}

值对象

A 值对象是一个没有标识的对象,但它代表一个概念。例如,Money 对象代表一个值,但不需要唯一的 ID。

// app/Domain/Order/Money.php
class Money {
    private $amount;
    private $currency;

    public function __construct($amount, $currency) {
        $this->amount = $amount;
        $this->currency = $currency;
    }

    public function getFormatted() {
        return "{$this->amount} {$this->currency}";
    }
}

存储库

A Repository 处理获取和持久化实体等域对象。存储库管理数据访问,而不是直接与数据库交互的域对象。

// app/Domain/Order/OrderRepositoryInterface.php
interface OrderRepositoryInterface {
    public function findById($id): ?Order;
    public function save(Order $order): void;
}

// app/Infrastructure/Order/EloquentOrderRepository.php
class EloquentOrderRepository implements OrderRepositoryInterface {
    public function findById($id): ?Order {
        // Fetch order using Eloquent
    }

    public function save(Order $order): void {
        // Save order using Eloquent
    }
}

服务

A Service 处理业务逻辑,例如创建订单或处理付款。您无需将此逻辑放入控制器中,而是将其封装在服务中。

// app/Domain/Order/CreateOrderService.php
class CreateOrderService {
    public function execute($data) {
        $order = new Order($data['id'], $data['status']);
        // Business logic for creating an order
    }
}

在 Laravel 中实现 DDD

现在您已经了解了关键组件,让我们通过一些实际示例来看看如何在 Laravel 中实现 DDD。

示例1:构建订单管理系统

假设您正在为电子商务网站构建订单管理系统。以下是 DDD 如何帮助您组织代码:

  1. 实体:您将有一个订单实体来代表每个订单,并具有 id 和 status 等属性。
  2. 值对象:您可以创建一个 Money 值对象来表示价格。
  3. Repositories:您将创建一个 OrderRepository 来在数据库中获取和存储订单。
  4. 服务:CreateOrderService 将处理创建新订单的逻辑。

这是基本流程:

// app/Http/Controllers/OrderController.php
class OrderController {
    private $createOrderService;

    public function __construct(CreateOrderService $createOrderService) {
        $this->createOrderService = $createOrderService;
    }

    public function store(Request $request) {
        $this->createOrderService->execute($request->all());
        return response()->json(['message' => 'Order created!']);
    }
}

示例 2:管理用户订阅

假设您正在管理 SaaS 平台的用户订阅。使用 DDD,您可以创建:

  • 代表每个用户订阅的订阅实体。
  • 用于管理订阅周期的持续时间值对象。
  • 处理数据访问的 SubscriptionRepository。
  • 用于处理续订订阅等业务逻辑的 SubscriptionService。

以下是处理订阅续订的方法:

// app/Domain/Subscription/RenewSubscriptionService.php
class RenewSubscriptionService {
    private $subscriptionRepository;

    public function __construct(SubscriptionRepositoryInterface $subscriptionRepository) {
        $this->subscriptionRepository = $subscriptionRepository;
    }

    public function renew($subscriptionId) {
        $subscription = $this->subscriptionRepository->findById($subscriptionId);
        $subscription->renew();
        $this->subscriptionRepository->save($subscription);
    }
}

Laravel 中 DDD 的优缺点

优点:

  • 更好的组织:代码围绕领域整齐地构建。
  • 可扩展性:更容易扩展和管理大型应用程序。
  • 可维护性:业务逻辑与基础设施问题分离。

缺点:

  • 学习曲线:DDD 引入了新概念,一开始可能会让人不知所措。
  • 小型项目的开销:为小型、简单的项目实施 DDD 可能会让人感觉有点大材小用。

最后的想法

Laravel 中的 DDD 可能看起来令人畏惧,但是一旦您开始从业务领域而不是技术层角度思考,它就开始有意义了。这一切都是为了随着项目的发展保持代码整洁、可维护和可扩展。

从小事做起。使用 DDD 原则重构应用程序中的一项功能,看看效果如何。随着时间的推移,您将开始欣赏它带来的组织性和清晰度。

祝你好运,编码愉快!

版本聲明 本文轉載於:https://dev.to/arafatweb/a-simple-guide-to-domain-driven-design-ddd-in-laravel-15cp?1如有侵犯,請聯絡[email protected]刪除
最新教學 更多>
  • 如何使用 Python 檢索 Github 儲存庫數據
    如何使用 Python 檢索 Github 儲存庫數據
    您的組織是否擁有太多github 儲存庫,並且您需要一種簡單的方法來總結和記錄每個儲存庫的內容以用於報告、儀表板或審計目的?下面是一個使用 Github API 完成該操作的快速腳本。 功能: get_repo_info(所有者,回購): 取得 GitHub 儲存庫擁有者的使用者名...
    程式設計 發佈於2024-11-08
  • 使用 useState 的狀態更新方法
    使用 useState 的狀態更新方法
    React 是用於開發動態和互動式使用者介面的最受歡迎的 JavaScript 程式庫之一。在開發應用程式時,狀態管理對於效能和使用者體驗至關重要。在這種情況下,useState 掛鉤是管理元件狀態的最常見方法之一。在本文中,我們將深入研究 useState. 的狀態更新方法 狀態更...
    程式設計 發佈於2024-11-08
  • 考慮到 libcurl 的可用性,何時適合在 PHP 中啟用「allow_url_fopen」?
    考慮到 libcurl 的可用性,何時適合在 PHP 中啟用「allow_url_fopen」?
    在 PHP 中允許「allow_url_fopen」:平衡行為開發人員經常要求在 PHP 中啟動「allow_url_fopen」。在本文中,我們將檢查目前的行業規格並評估允許此功能是否仍然謹慎,特別是在 libcurl 可用的情況下。 當前行業規範對於大多數 Web 應用程序,啟用“allow_u...
    程式設計 發佈於2024-11-08
  • 何時在 jQuery.parseJSON 中使用單引號和雙引號?
    何時在 jQuery.parseJSON 中使用單引號和雙引號?
    jQuery.parseJSON 中的單引號與雙引號使用jQuery 的parseJSON 方法時,使用者可能會遇到行為差異,具體取決於是單引號還是雙引號雙引號用於將JSON 字串括起來。在本文中,我們將探討這些差異。 雙引號:標準方法根據 JSON 標準,雙引號被認為是括起的首選方法JSON 字串...
    程式設計 發佈於2024-11-08
  • 如何處理多處理 Python 應用程式中的日誌記錄?
    如何處理多處理 Python 應用程式中的日誌記錄?
    Python 中的多處理日誌記錄使用Python 的多處理模組時,重要的是要考慮日誌記錄實踐,以避免因多個進程寫入而導致錯誤同時處理相同的檔案句柄。預設情況下,mp.get_logger() 提供的多處理感知記錄器可確保 sys.stderr 中正確的鎖定機制。 但是,不支援多處理感知的模組可能需要...
    程式設計 發佈於2024-11-08
  • 答:我如何運行特定的phinx seeder並在phpunit中取得產生的記錄?
    答:我如何運行特定的phinx seeder並在phpunit中取得產生的記錄?
    這個答案解決了我遇到的一個問題:在 phpunit 上運行 Phinx 播種者: 回答回覆:我如何運行特定的phinx seeder並在phpunit中取得產生的記錄? ...
    程式設計 發佈於2024-11-08
  • 如何以程式設計方式為 LinearLayout 中的按鈕新增邊距?
    如何以程式設計方式為 LinearLayout 中的按鈕新增邊距?
    LinearLayout 中的動態邊距LinearLayout 中的動態邊距在Android 開發中,佈局在組織和顯示使用者介面元素方面發揮著至關重要的作用。佈局的一個常見要求是能夠指定元素之間的邊距。雖然 XML 提供了一種直觀的方式來定義邊距,但開發人員可能需要以程式設計方式建立佈局以確保靈活性...
    程式設計 發佈於2024-11-08
  • 如何使用 PowerMock 和 Mockito 有效模擬私有方法?
    如何使用 PowerMock 和 Mockito 有效模擬私有方法?
    使用PowerMock 模擬私有方法的替代解決方案儘管最初提出的使用PowerMock 的解決方案遇到了困難,但事實證明,另一種方法是成功的。使用 Mockito 和 PowerMock 的組合,可以有效地模擬私有方法。 如提供的程式碼片段所示,類別 CodeWithPrivateMethod 擁有...
    程式設計 發佈於2024-11-08
  • 如何在 PHP 中將列式資料結構轉換為基於行的格式?
    如何在 PHP 中將列式資料結構轉換為基於行的格式?
    將多維列式資料重新排序為基於行的結構給定一個具有面向列資料的關聯數組,任務是將其轉置為由行組成的多維數組。原始數組中的資料按列排列,目標是將同一列的值合併到行中。 原始陣列:$where = [ 'id' => [ 12, 13, 14 ...
    程式設計 發佈於2024-11-08
  • Next.JS 或 Nuxt.JS 哪個最好
    Next.JS 或 Nuxt.JS 哪個最好
    The ability to build scalable and seamless web applications quickly is the dream of every web developer. As a result, the importance of frameworks in ...
    程式設計 發佈於2024-11-08
  • 了解 RESTful API 和 Web 服務:主要差異和用例
    了解 RESTful API 和 Web 服務:主要差異和用例
    在現代軟體開發領域,RESTful API 和 Web 服務都是實現不同系統之間無縫通訊的基礎。雖然這些術語經常互換使用,但它們代表具有獨特特徵和用例的不同概念。對於旨在建立高效、可互通且可擴展的應用程式的開發人員來說,掌握 RESTful API 和 Web 服務 之間的差異至關重要。在本節中,我...
    程式設計 發佈於2024-11-08
  • React 應用程式的基本設計模式:升級您的組件遊戲
    React 應用程式的基本設計模式:升級您的組件遊戲
    如果您已经进入 React 世界一段时间,您可能听说过“这只是 JavaScript”这句话。虽然这是事实,但这并不意味着我们不能从一些经过验证的模式中受益,使我们的 React 应用程序更易于维护、可重用并且使用起来更加愉快。让我们深入研究一些基本的设计模式,这些模式可以让你的 React 组件从...
    程式設計 發佈於2024-11-08
  • 使用 PHP 建立 API 和 Web 服務
    使用 PHP 建立 API 和 Web 服務
    使用 PHP 建立 API 和 Web 服務涉及以下步驟:建立 PHP 環境,安裝 PHP、Apache 伺服器和 mod_php 模組。建立 API,編寫 PHP 腳本處理請求並回傳回應。建立 Web 服務,使用 PHP 框架或純 PHP 來建立伺服器。實戰案例:建立用戶註冊 API,處理 POS...
    程式設計 發佈於2024-11-08
  • Restful 路由 - Flask API 範例
    Restful 路由 - Flask API 範例
    Restful 路由致力於使所有不同應用程式的路由保持一致。 REST 是表述性狀態轉移。它以一致的、人類可讀的、機器可讀的方式使用 HTTP。 標準是 GET、POST、PATCH、PUT 和 DELETE。 下面將給出 Flask API 資料庫中的幾個靜態路由的範例,用於從前端獲取/向前端...
    程式設計 發佈於2024-11-08
  • ## 如何在沒有反向引用的情況下匹配 Go 正規表示式中的重複字元?
    ## 如何在沒有反向引用的情況下匹配 Go 正規表示式中的重複字元?
    在Go 的正規表示式中符合重複字元在Go 的正規表示式中,符合重複字元可能是一個挑戰,因為不支援反向引用。這可能會令人沮喪,特別是當您需要執行複雜的模式匹配任務時。 要解決此限制,有兩種可能的解決方案:使用替代正則表達式庫:一種選擇是使用支援反向引用的第三方正規表示式庫。一個流行的選擇是“glenn...
    程式設計 發佈於2024-11-08

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3