首页 后端开发 php教程 构建 Symfony 项目的另一种方法

构建 Symfony 项目的另一种方法

Dec 05, 2024 am 03:55 AM

MVC 服务架构在 Symfony 项目中非常常见,感觉像是唯一的方法。它简单、熟悉、有效……直到它不起作用为止。随着项目的增长,裂缝开始显现:业务逻辑无处不在,应用程序行为不清楚,维护代码变得痛苦。虽然这是最常见的方法,但 Symfony 并不强迫您坚持使用它。

如果有更好的方法呢?


使用 MVC 服务架构的挫折

 

领域逻辑无处不在

随着项目的发展,业务逻辑往往会分布在整个代码库中。项目的每一层——控制器、服务、表单、实体——最终都包含域模型的各个部分。这使得专注于任何特定部分变得越来越困难。

 

项目边界不明确

当您的架构是围绕技术层组织的时,随着项目的发展,识别不同上下文之间的清晰边界变得更加困难。这种缺乏清晰度可能会导致紧密耦合的代码和维护挑战。

Another Way to Structure your Symfony Project

 

项目行为不明确

由于默认架构强调技术层,因此理解项目的行为变得相当具有挑战性。您可能会推断某些实体由特定服务管理或猜测数据库模式,但项目的实际行为(最重要的方面)仍然不清楚和隐含。

Another Way to Structure your Symfony Project

 

不同的生命周期

当业务逻辑分散在整个项目中并与实现细节混合时,很难独立地发展它们。随着时间的推移,业务逻辑的生命周期往往比实现细节(例如框架、第三方 API 或数据库)的生命周期长得多。每当依赖项中发生哪怕是很小的更改时,这种不匹配都会迫使您重写大部分代码。


构建架构的更好方法

 

隔离业务逻辑

为了在需要时更容易专注于业务逻辑,第一步是将其与项目的其余部分隔离。为此,请创建一个 Domain 文件夹。该文件夹成为项目的核心,其中业务逻辑使用纯 PHP 对象进行建模,不依赖于实现细节。虽然项目的其余部分依赖于此文件夹,但 Domain 文件夹不依赖于任何人。

在“域”文件夹内,文件应按域目的而不是技术目的进行分组。这意味着这里没有实体、服务或控制器文件夹,只有与功能或域概念相对应的文件夹名称。

Another Way to Structure your Symfony Project

 

域的前门

项目最重要的方面是它做什么,它可以处理的操作。这些操作代表了项目的行为,并且应该作为访问业务逻辑的唯一方法。为了反映这一点,请创建一个 Application 文件夹,明确展示项目的所有行为。例如,作为项目的新开发人员,我应该能够通过查看此文件夹一眼就了解该项目能够做什么。

Another Way to Structure your Symfony Project

 

连接外部世界

使用 AppDomain 文件夹,可以轻松专注于业务逻辑。然而,在某些时候,这个业务逻辑需要与外部系统进行交互。要处理此问题,请创建第三个名为 Infrastruct 的文件夹,其中包含所有实现细节,例如特定于框架的代码、数据库连接和库。

Infra设施文件夹中的文件取决于App和Domain文件。例如,他们可能从 App 文件夹调用应用程序处理程序或实现 Domain 文件夹中定义的接口。

Another Way to Structure your Symfony Project

具体来说,在 Symfony 中,这涉及修改 Controller 文件夹并声明哪些服务实现哪些接口。

# config/routes.yaml

controllers:
    resource:
        path: ../src/Catalog/Infrastructure/Controller/
        namespace: App\Catalog\Infrastructure\Controller
    type: attribute
登录后复制

 

揭示界限

随着项目的发展,您可能会注意到业务逻辑的某些部分值得在架构中拥有自己的空间。一个好的指标是同一个术语根据上下文开始具有不同的含义。例如,“产品”一词可能指的是工厂产品、仓库产品或电子商务产品,每种产品都需要自己的模型。神物也可以是一个很好的指标; User 类在 Symfony 项目中经常出现此类问题。

当这种情况发生时,就该将其提取出来并让其业务逻辑独立演化。

一些上下文将构成您项目的核心,而其他上下文将支持它。通用上下文(例如 Auth)可以使用更简单的架构,因为它们不是您的域的中心

Another Way to Structure your Symfony Project

在这张图中,我们可以看到 Auth 上下文使用标准的 Symfony 结构,Order 和 Catalog 上下文使用以域为中心的架构,Shipping 上下文使用以功能为中心的架构。

 

增量模块化

如果特定上下文增长到需要独立扩展的程度,请考虑将其拆分为单独的部署单元。

但是,不要急于进行这一步。首先使您的项目模块化,如果您发现上下文需要单独扩展,则单独部署它。
仅当出现组织挑战时才拆分代码库,例如两个团队在同一代码库上难以协作。

Another Way to Structure your Symfony Project

走得更远
  • Simon Brown - 模块化巨石

概念

在探索这些解决方案时,我们应用了一些工艺概念。让我们命名并简要解释它们,以便您可以更深入地了解每一个。

 

无处不在的语言

这个不寻常的术语背后隐藏着一个非常简单的概念。通用语言是您的团队用来描述域模型的词汇。这些词汇应该记录在案,并在产品对话、代码库等各处一致使用。

具体来说,在有界上下文的根部创建一个 markdown 文件,并将产品人员、领域专家和技术团队聚集在一起来定义项目的每个概念。

走得更远

  • Eric Evans - DDD - 第 2 章:沟通和语言的使用
  • 马丁·福勒 - 无处不在的语言

 

有界上下文

有界上下文定义了项目内的语言边界,分隔了系统中通用语言不再对齐的部分。上下文地图和事件风暴等工具可以帮助识别这些边界。

有界上下文是一个抽象概念;它可以通过多种方式实现,从模块化整体中的简单文件夹到微服务架构中的集群。

走得更远

  • Eric Evans - DDD - 第四部分:战略设计
  • Vaughn Vernon - IDDD - 第 2 章:域、子域和有界上下文
  • Martin Fowler - 有界上下文

 

端口和适配器、六边形、洋葱形和简洁架构

所有这些架构的目的是将业务逻辑与实现细节隔离。无论您使用端口和适配器、六角形还是干净架构,核心思想都是使业务逻辑框架与框架无关并且易于测试。

一旦您记住了这一点,就会有各种各样的实现,而最好的实现取决于您的上下文和偏好。这种架构的一个主要优点是,通过隔离您的业务逻辑,它可以实现更高效的测试。

走得更远

  • Alistair Cockburn - 六角形建筑
  • 鲍勃叔叔 - 干净的建筑
  • Herberto Graca - DDD、六边形、洋葱、清洁、CQRS,……我如何将它们放在一起

 

尖叫建筑

组织文件夹和文件以“尖叫”业务逻辑的想法被称为尖叫架构。这个概念强调代码的结构应该使项目的目的立即清晰。目标是让新开发人员一目了然地了解项目的用途。

我强烈建议阅读鲍勃叔叔关于该主题的文章 - 他与房屋规划的比较特别富有洞察力。

走得更远

  • 鲍勃叔叔 - 尖叫建筑

 

垂直切片架构

垂直切片按功能组织您的项目,允许每个功能独立发展。它使您能够根据复杂性和成熟度将不同的架构应用于不同的功能。

虽然这个想法很有趣,但它需要高技能的工程师来有效地实现和维护这样的架构。

走得更远

  • Jimmy Bogard - 垂直切片架构
  • CodeOpinion - 垂直切片架构,而不是层!

最后的想法

构建 Symfony 项目的方式对其可扩展性、可维护性和清晰度有着深远的影响。通过隔离您的业务逻辑并使行为明确,您将创建一个更易于理解和发展的系统。

如果您对这些想法不熟悉,请不要担心,软件工艺是一个旅程,而不是目的地。这些概念一开始可能看起来令人难以接受,但每个概念都将帮助您为您的业务创造更多价值。

有疑问或想分享您的经验吗?将它们放入评论中!请继续关注下一篇文章?

以上是构建 Symfony 项目的另一种方法的详细内容。更多信息请关注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脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.聊天命令以及如何使用它们
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

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

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

在PHP API中说明JSON Web令牌(JWT)及其用例。 在PHP API中说明JSON Web令牌(JWT)及其用例。 Apr 05, 2025 am 12:04 AM

JWT是一种基于JSON的开放标准,用于在各方之间安全地传输信息,主要用于身份验证和信息交换。1.JWT由Header、Payload和Signature三部分组成。2.JWT的工作原理包括生成JWT、验证JWT和解析Payload三个步骤。3.在PHP中使用JWT进行身份验证时,可以生成和验证JWT,并在高级用法中包含用户角色和权限信息。4.常见错误包括签名验证失败、令牌过期和Payload过大,调试技巧包括使用调试工具和日志记录。5.性能优化和最佳实践包括使用合适的签名算法、合理设置有效期、

解释PHP中晚期静态结合的概念。 解释PHP中晚期静态结合的概念。 Mar 21, 2025 pm 01:33 PM

文章讨论了PHP 5.3中引入的PHP中的晚期静态结合(LSB),从而允许静态方法的运行时分辨率调用以获得更灵活的继承。 LSB的实用应用和潜在的触摸

描述扎实的原则及其如何应用于PHP的开发。 描述扎实的原则及其如何应用于PHP的开发。 Apr 03, 2025 am 12:04 AM

SOLID原则在PHP开发中的应用包括:1.单一职责原则(SRP):每个类只负责一个功能。2.开闭原则(OCP):通过扩展而非修改实现变化。3.里氏替换原则(LSP):子类可替换基类而不影响程序正确性。4.接口隔离原则(ISP):使用细粒度接口避免依赖不使用的方法。5.依赖倒置原则(DIP):高低层次模块都依赖于抽象,通过依赖注入实现。

框架安全功能:防止漏洞。 框架安全功能:防止漏洞。 Mar 28, 2025 pm 05:11 PM

文章讨论了框架中的基本安全功能,以防止漏洞,包括输入验证,身份验证和常规更新。

自定义/扩展框架:如何添加自定义功能。 自定义/扩展框架:如何添加自定义功能。 Mar 28, 2025 pm 05:12 PM

本文讨论了将自定义功能添加到框架上,专注于理解体系结构,识别扩展点以及集成和调试的最佳实践。

如何用PHP的cURL库发送包含JSON数据的POST请求? 如何用PHP的cURL库发送包含JSON数据的POST请求? Apr 01, 2025 pm 03:12 PM

使用PHP的cURL库发送JSON数据在PHP开发中,经常需要与外部API进行交互,其中一种常见的方式是使用cURL库发送POST�...

如何在系统重启后自动设置unixsocket的权限? 如何在系统重启后自动设置unixsocket的权限? Mar 31, 2025 pm 11:54 PM

如何在系统重启后自动设置unixsocket的权限每次系统重启后,我们都需要执行以下命令来修改unixsocket的权限:sudo...

See all articles