laracrafthub/ddd-template

一个专为使用领域驱动设计(DDD)构建Web应用程序而设计的、可立即使用的Laravel模板。

安装: 0

依赖: 0

建议者: 0

安全: 0

星标: 1

关注者: 1

分支: 1

开放问题: 5

类型:项目


README

DDD-Template

DDD-Template是一个专为使用领域驱动设计(DDD)原理开发Web应用程序而设计的可立即使用的Laravel模板。这个模板简化了构建强大和可扩展应用程序的过程,确保项目有一个坚实的基础架构。

✨ 主要功能

  • Laravel框架:利用Laravel的强大和简洁。

  • 领域驱动设计:采用DDD原理,有效实现复杂领域建模。

  • 可扩展性和可维护性:结构化以支持大规模应用程序和易于维护。

🧙 这个模板适合谁?

这个为Laravel设计的领域驱动设计(DDD)模板是为寻求以下目标的开发者和团队设计的:

  • 采用领域驱动设计:理想适用于那些希望在Laravel项目中实施DDD原理,促进软件与底层商业概念的深入联系的开发者。
  • 构建大型和复杂的应用程序:特别适用于大型应用程序,其中将业务逻辑与应用程序和基础设施代码分离对于维护性和可扩展性至关重要。
  • 改进代码组织:适合那些旨在增强代码结构,使其更易于阅读、维护和导航的开发者。
  • 促进团队协作:非常适合那些需要清晰和一致的编码结构的团队,尤其是在大型或分布式团队中,可以促进协作。
  • 专注于业务逻辑:适合那些希望集中精力实现业务规则和逻辑,而不被框架特定细节所困扰的开发者。
  • 确保高质量代码:适合那些优先考虑测试并希望采用结构化方法进行单元和集成测试的开发者。
  • 采用高级Laravel实践:适合那些希望在项目中采用高级实践和架构模式的经验丰富的Laravel开发者。

无论您是独立开发者、小型团队的一员,还是大型企业项目的一部分,这个模板都提供了一个结构化的方法来实现Laravel中的DDD,使技术实现与业务需求保持一致,并确保长期项目的成功和可维护性。

🧬 项目结构

项目组织成三个主要层,每层都位于"app/"文件夹内的子文件夹中

  1. 应用层
    • 位置Application/
    • 目的:这一层包含所有应用程序逻辑,并在领域和基础设施层之间充当桥梁。它包括控制器、服务和驱动应用程序流程的其他机制。
    • 内容:所有原本位于Laravel的app/目录中的内容都已移至此处。主要应包含框架特定服务:特定于Laravel的服务,例如控制器、中间件、服务提供者、广播频道等。
  2. 领域层
    • 位置Domain/
    • 目的:专门用于存放所有业务逻辑和领域特定代码。这一层与框架无关,专注于业务规则。
    • 内容:
      • 实体:表示业务对象及其固有逻辑的核心类。这些通常是包含与业务域相关的状态和行为的相关丰富的模型。
      • 值对象:代表领域描述性方面的不可变对象,没有概念上的身份(例如,货币、日期范围、地址)。
      • 聚合:一组可以被视为单个单元的领域对象。聚合将有一个组件对象是聚合根。
      • 领域服务:无状态的、封装不自然适合实体或值对象内的领域逻辑的服务。
      • 领域事件:表示在领域内发生的重大事件的某些事件。它们用于以松耦合的方式在不同部分的应用程序中触发副作用。
      • 仓储接口:如何从基础设施层检索数据领域层的抽象,确保关注点的分离。
      • 工厂:用于创建复杂领域对象的类或方法。
      • 规范:封装某些业务逻辑的类,通常用于验证或选择标准。
      • 策略:表示业务规则或决策的类或方法。
  3. 基础设施层
    • 位置: Infrastructure/
    • 目的:包含定义在领域层中的接口的实现,如仓储或外部服务。这一层与数据库和外部系统交互。
    • 内容:
      • 仓储:数据访问领域接口的实现,通常涉及Eloquent模型。
      • 外部服务集成:集成外部API和服务的代码。
      • 工具和助手:辅助基础设施相关任务的工具类和辅助函数。
      • 邮件和通知服务:发送邮件和通知的基础设施。
      • 队列管理:作业队列和工作者的实现。

🧪 测试结构

为确保健壮性和可靠性,模板包含一个全面的测试设置

单元测试

  • 位置: tests/Unit/
  • 目的:专注于测试小的、孤立的代码片段,主要来自领域/基础设施层,但不仅限于这些。
  • 特性:
    • 利用PHPUnit的基类测试用例PHPUnit\Framework\TestCase,而不是Illuminate\Foundation\Testing\TestCase
    • 避免启动整个Laravel框架以提高执行速度(查看UnitTestCase)。
    • 包括用于轻松测试请求验证器的助手(查看测试请求验证器的示例)和使用类似工厂的模式的构建Eloquent模型(查看使用示例)。

集成测试

  • 位置: tests/Integration/

  • 目的:测试应用程序不同部分之间的交互,确保它们按预期协同工作。

  • 特性:

    • 全面覆盖:确保模块集成时按预期工作并满足业务要求。
    • 数据库交互:涉及实际数据库操作的测试,以验证数据持久性、检索和数据库事务的完整性。
    • 环境模拟:利用与生产设置相似测试环境,包括配置,以确保测试条件的真实性。
    • API测试:验证RESTful API,确保端点在各种情况下表现如预期。
    • 中间件和路由测试:确保HTTP请求被正确处理和路由,包括中间件的功能。
    • 服务集成:验证外部服务和API是否正确集成,并在应用程序中按预期交互。
    • 性能检查:基本性能测试,以识别组件协同工作时潜在的瓶颈。
    • 错误处理:测试应用程序对错误输入和意外场景的响应,以确保稳健的错误处理。

⚙️ 持续集成(CI)设置

此模板集成了强大的持续集成(CI)设置,以确保代码质量、一致性和可靠性。以下CI作业已配置

  1. Laravel Pint (来源)
    • 目的:自动格式化代码以符合Laravel的编码标准。
    • 操作:运行Laravel Pint以确保所有代码遵循规定的样式指南。
  2. PHPStan(应用程序代码)
    • 目的:对应用程序代码进行静态分析,以检测潜在的错误和错误。
    • 配置:针对Application/Domain/Infrastructure/文件夹,使用特定的PHPStan配置以满足DDD要求。
  3. PHPStan(测试)
    • 目的:确保测试代码的质量和可靠性。
    • 配置:使用特定的PHPStan配置分析tests/文件夹,以适应测试场景。
  4. Rector (来源)
    • 目的:自动化代码重构,确保现代和高效的代码实践。
    • 操作:运行Rector重构代码库,提高代码质量和可维护性。
  5. 单元测试
    • 目的:验证源代码各个单元的正确性。
    • 操作:执行单元测试,确保应用程序小型、独立部分的完整性和功能。
  6. 集成测试(并行执行)
    • 目的:测试应用程序不同层和组件之间的交互。
    • 配置:分为三个单独的作业,每个作业专注于DDD的特定层。
    • 并行执行:利用"brianium/paratest"包并行运行测试,显著加快了这些通常较慢的测试的执行时间。
  7. Renovate 依赖管理 (来源)
    • 目的:自动管理项目依赖项,确保它们是最新的且安全的。
    • 功能:Renovate定期扫描项目依赖项,并提交拉取请求以更新它们。这包括直接依赖项和间接依赖项。
    • 优势:
      • 自动更新:无需人工干预即可保持依赖项更新,节省时间和精力。
      • 安全性:及时更新具有已知漏洞的依赖项,提高应用程序的安全性。
      • 可定制性:可根据特定项目需求进行配置,例如安排更新和定义版本控制策略。
    • 一致性:确保所有开发和生产环境中的依赖项版本一致。
    • 集成:虽然不是传统的CI任务,但Renovate可以无缝集成到开发流程中,通过保持代码库的当前性和安全性来补充其他CI过程。

CI配置在维持高标准的代码质量和确保代码库的更改和新增内容不会引入回归或破坏现有功能方面发挥着至关重要的作用。其中最重要的作用之一是帮助我们严格遵守领域驱动设计(DDD)原则。此自动过程有助于早期发现偏离这些原则的情况,确保开发始终符合DDD的核心概念。通过这样做,它使开发过程更加高效、可靠,并与项目的战略目标保持一致。

🚧 将DDD与Laravel集成的挑战

Eloquent ORM和层分离

将领域驱动设计(DDD)集成到Laravel框架中的一大挑战是将领域层与基础设施层分离,尤其是在使用Eloquent ORM时。作为Active Record实现,Eloquent倾向于模糊领域和持久化层之间的界限。本部分将突出这一挑战以及我们应对这一挑战的方法。

  • Eloquent的Active Record模式:Eloquent ORM遵循Active Record模式,其中模型对象直接与数据库表相关联。这种模式本质上将业务逻辑(领域)与数据持久化(基础设施)耦合在一起,这与DDD原则中领域逻辑和基础设施关注点之间清晰分离的原则相矛盾。

  • 方法和妥协:

    • 选择性使用Eloquent:虽然Eloquent是一个功能强大且方便的ORM,但我们限制其使用,以确保它不会主导领域逻辑。在Eloquent的紧密耦合干扰DDD原则的领域,我们选择替代方法。
    • 仓库模式:为了在Eloquent和领域层之间进行调解,我们实现了仓库模式。仓库与Eloquent模型接口,允许大多数领域层对底层的ORM实现保持无知。
    • 专注领域模型:我们努力使我们的领域模型专注于业务逻辑,尽可能地将数据持久化关注点委托给基础设施层。
    • 平衡DDD与实用性:认识到Eloquent在Laravel环境中的实际好处,我们平衡对DDD的严格遵循与Laravel功能的实用使用。这种平衡使我们能够利用Laravel的优势,同时仍保持与DDD一致的关注点分离。
  • 持续改进:随着Laravel框架的发展,以及我们获得更多见解,我们不断改进我们的方法,以更好地与DDD原则保持一致,同时不牺牲框架的好处。

在努力保持领域和基础设施关注点之间的清晰分离过程中,我们采用了处理Eloquent模型的一种新颖方法

  • Eloquent模型的双类策略:

    • 领域层类:在领域层中,每个Eloquent模型主要封装实体业务逻辑。此类关注于领域实体的核心业务规则和行为。
    • 基础设施层类:在基础设施层中,定义一个相应的Eloquent模型来处理特定于基础设施的方面。这包括定义关系(belongsTo、hasMany等)、casts、可填充字段以及与数据库交互等基础设施相关特质的使用。
    • 类扩展:领域层类扩展了基础设施层类。这种结构允许领域模型继承必要的数据库和ORM功能,同时保持业务逻辑的分离和专注。这样,领域模型就与直接数据库操作保持隔离,但仍可受益于Eloquent提供的基础设施能力。
  • 理由和优势:

    • 关注点分离:这种双类策略强化了业务逻辑(领域)与数据库和基础设施关注点的分离,更紧密地遵循了DDD原则。
    • 利用Eloquent的优势:在保持领域模型专注于业务规则的同时,这种方法仍然允许我们利用Eloquent在数据库交互和关系方面的全部功能和便利性。
    • 保持灵活性:这种设置提供了灵活性,可以在不影响与基础设施相关代码的情况下独立地演进领域逻辑,使系统更能适应业务需求的变化。

通过这种创新的结构化Eloquent模型,我们在严格应用DDD原则和Laravel的Eloquent ORM提供的实际优势之间找到了平衡。

这个挑战反映了软件架构中常见的理想设计原则与特定框架或工具的实用性之间的紧张关系。我们的方法旨在寻找平衡,确保我们使用Laravel和Eloquent服务于我们的DDD目标,而不会过度牺牲设计。

🧑‍💻 本地开发任务

本项目包含一个旨在简化常见开发任务执行的任务文件。这些任务可以在本地运行,从而提高开发效率。您可以在此处找到有关可用任务的描述。

🤝 贡献

欢迎为增强此DDD模板做出贡献(有关详细信息,请参阅CONTRIBUTING)。请遵循标准的GitHub拉取请求流程提交您的更改。

📝 许可证 ©

本项目受MIT许可证许可。