MVC 服务架构在 Symfony 项目中非常常见,感觉像是唯一的方法。它简单、熟悉、有效……直到它不起作用为止。随着项目的增长,裂缝开始显现:业务逻辑无处不在,应用程序行为不清楚,维护代码变得痛苦。虽然这是最常见的方法,但 Symfony 并不强迫您坚持使用它。
如果有更好的方法呢?
使用 MVC 服务架构的挫折
领域逻辑无处不在
随着项目的发展,业务逻辑往往会分布在整个代码库中。项目的每一层——控制器、服务、表单、实体——最终都包含域模型的各个部分。这使得专注于任何特定部分变得越来越困难。
项目边界不明确
当您的架构是围绕技术层组织的时,随着项目的发展,识别不同上下文之间的清晰边界变得更加困难。这种缺乏清晰度可能会导致紧密耦合的代码和维护挑战。
项目行为不明确
由于默认架构强调技术层,因此理解项目的行为变得相当具有挑战性。您可能会推断某些实体由特定服务管理或猜测数据库模式,但项目的实际行为(最重要的方面)仍然不清楚和隐含。
不同的生命周期
当业务逻辑分散在整个项目中并与实现细节混合时,很难独立地发展它们。随着时间的推移,业务逻辑的生命周期往往比实现细节(例如框架、第三方 API 或数据库)的生命周期长得多。每当依赖项中发生哪怕是很小的更改时,这种不匹配都会迫使您重写大部分代码。
构建架构的更好方法
隔离业务逻辑
为了在需要时更容易专注于业务逻辑,第一步是将其与项目的其余部分隔离。为此,请创建一个 Domain 文件夹。该文件夹成为项目的核心,其中业务逻辑使用纯 PHP 对象进行建模,不依赖于实现细节。虽然项目的其余部分依赖于此文件夹,但 Domain 文件夹不依赖于任何人。
在“域”文件夹内,文件应按域目的而不是技术目的进行分组。这意味着这里没有实体、服务或控制器文件夹,只有与功能或域概念相对应的文件夹名称。
域的前门
项目最重要的方面是它做什么,它可以处理的操作。这些操作代表了项目的行为,并且应该作为访问业务逻辑的唯一方法。为了反映这一点,请创建一个 Application 文件夹,明确展示项目的所有行为。例如,作为项目的新开发人员,我应该能够通过查看此文件夹一眼就了解该项目能够做什么。
连接外部世界
使用 App 和 Domain 文件夹,可以轻松专注于业务逻辑。然而,在某些时候,这个业务逻辑需要与外部系统进行交互。要处理此问题,请创建第三个名为 Infrastruct 的文件夹,其中包含所有实现细节,例如特定于框架的代码、数据库连接和库。
Infra设施文件夹中的文件取决于App和Domain文件。例如,他们可能从 App 文件夹调用应用程序处理程序或实现 Domain 文件夹中定义的接口。
具体来说,在 Symfony 中,这涉及修改 Controller 文件夹并声明哪些服务实现哪些接口。
# config/routes.yaml controllers: resource: path: ../src/Catalog/Infrastructure/Controller/ namespace: App\Catalog\Infrastructure\Controller type: attribute
揭示界限
随着项目的发展,您可能会注意到业务逻辑的某些部分值得在架构中拥有自己的空间。一个好的指标是同一个术语根据上下文开始具有不同的含义。例如,“产品”一词可能指的是工厂产品、仓库产品或电子商务产品,每种产品都需要自己的模型。神物也可以是一个很好的指标; User 类在 Symfony 项目中经常出现此类问题。
当这种情况发生时,就该将其提取出来并让其业务逻辑独立演化。
一些上下文将构成您项目的核心,而其他上下文将支持它。通用上下文(例如 Auth)可以使用更简单的架构,因为它们不是您的域的中心
在这张图中,我们可以看到 Auth 上下文使用标准的 Symfony 结构,Order 和 Catalog 上下文使用以域为中心的架构,Shipping 上下文使用以功能为中心的架构。
增量模块化
如果特定上下文增长到需要独立扩展的程度,请考虑将其拆分为单独的部署单元。
但是,不要急于进行这一步。首先使您的项目模块化,如果您发现上下文需要单独扩展,则单独部署它。
仅当出现组织挑战时才拆分代码库,例如两个团队在同一代码库上难以协作。
走得更远
- 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中文网其他相关文章!

Laravel使用其直观的闪存方法简化了处理临时会话数据。这非常适合在您的应用程序中显示简短的消息,警报或通知。 默认情况下,数据仅针对后续请求: $请求 -

PHP客户端URL(curl)扩展是开发人员的强大工具,可以与远程服务器和REST API无缝交互。通过利用Libcurl(备受尊敬的多协议文件传输库),PHP curl促进了有效的执行

PHP日志记录对于监视和调试Web应用程序以及捕获关键事件,错误和运行时行为至关重要。它为系统性能提供了宝贵的见解,有助于识别问题并支持更快的故障排除

Laravel 提供简洁的 HTTP 响应模拟语法,简化了 HTTP 交互测试。这种方法显着减少了代码冗余,同时使您的测试模拟更直观。 基本实现提供了多种响应类型快捷方式: use Illuminate\Support\Facades\Http; Http::fake([ 'google.com' => 'Hello World', 'github.com' => ['foo' => 'bar'], 'forge.laravel.com' =>

您是否想为客户最紧迫的问题提供实时的即时解决方案? 实时聊天使您可以与客户进行实时对话,并立即解决他们的问题。它允许您为您的自定义提供更快的服务

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


热AI工具

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

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

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

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

PhpStorm Mac 版本
最新(2018.2.1 )专业的PHP集成开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

EditPlus 中文破解版
体积小,语法高亮,不支持代码提示功能

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