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

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
unset()和session_destroy()有什么区别?unset()和session_destroy()有什么区别?May 04, 2025 am 12:19 AM

Thedifferencebetweenunset()andsession_destroy()isthatunset()clearsspecificsessionvariableswhilekeepingthesessionactive,whereassession_destroy()terminatestheentiresession.1)Useunset()toremovespecificsessionvariableswithoutaffectingthesession'soveralls

在负载平衡的情况下,什么是粘性会话(会话亲和力)?在负载平衡的情况下,什么是粘性会话(会话亲和力)?May 04, 2025 am 12:16 AM

stickysessensureuserRequestSarerOutedTothesMeServerForsessionDataConsisterency.1)sessionIdentificeAssificationAssigeaSsignAssignSignSuserServerServerSustersusiseCookiesorUrlModifications.2)一致的ententRoutingDirectSsssssubsequeSssubsequeSubsequestrequestSameSameserver.3)loadBellankingDisteributesNebutesneNewuserEreNevuseRe.3)

PHP中有哪些不同的会话保存处理程序?PHP中有哪些不同的会话保存处理程序?May 04, 2025 am 12:14 AM

phpoffersvarioussessionsionsavehandlers:1)文件:默认,简单的ButMayBottLeneckonHigh-trafficsites.2)Memcached:高性能,Idealforsforspeed-Criticalapplications.3)REDIS:redis:similartomemememememcached,withddeddeddedpassistence.4)withddeddedpassistence.4)databases:gelifforcontrati forforcontrati,有用

PHP中的会话是什么?为什么使用它们?PHP中的会话是什么?为什么使用它们?May 04, 2025 am 12:12 AM

PHP中的session是用于在服务器端保存用户数据以在多个请求之间保持状态的机制。具体来说,1)session通过session_start()函数启动,并通过$_SESSION超级全局数组存储和读取数据;2)session数据默认存储在服务器的临时文件中,但可通过数据库或内存存储优化;3)使用session可以实现用户登录状态跟踪和购物车管理等功能;4)需要注意session的安全传输和性能优化,以确保应用的安全性和效率。

说明PHP会话的生命周期。说明PHP会话的生命周期。May 04, 2025 am 12:04 AM

PHPsessionsstartwithsession_start(),whichgeneratesauniqueIDandcreatesaserverfile;theypersistacrossrequestsandcanbemanuallyendedwithsession_destroy().1)Sessionsbeginwhensession_start()iscalled,creatingauniqueIDandserverfile.2)Theycontinueasdataisloade

绝对会话超时有什么区别?绝对会话超时有什么区别?May 03, 2025 am 12:21 AM

绝对会话超时从会话创建时开始计时,闲置会话超时则从用户无操作时开始计时。绝对会话超时适用于需要严格控制会话生命周期的场景,如金融应用;闲置会话超时适合希望用户长时间保持会话活跃的应用,如社交媒体。

如果会话在服务器上不起作用,您将采取什么步骤?如果会话在服务器上不起作用,您将采取什么步骤?May 03, 2025 am 12:19 AM

服务器会话失效可以通过以下步骤解决:1.检查服务器配置,确保会话设置正确。2.验证客户端cookies,确认浏览器支持并正确发送。3.检查会话存储服务,如Redis,确保其正常运行。4.审查应用代码,确保会话逻辑正确。通过这些步骤,可以有效诊断和修复会话问题,提升用户体验。

session_start()函数的意义是什么?session_start()函数的意义是什么?May 03, 2025 am 12:18 AM

session_start()iscucialinphpformanagingusersessions.1)ItInitiateSanewsessionifnoneexists,2)resumesanexistingsessions,and3)setsasesessionCookieforContinuityActinuityAccontinuityAcconActInityAcconActInityAcconAccRequests,EnablingApplicationsApplicationsLikeUseAppericationLikeUseAthenticationalticationaltication and PersersonalizedContentent。

See all articles

热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

好用且免费的代码编辑器

安全考试浏览器

安全考试浏览器

Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。

SecLists

SecLists

SecLists是最终安全测试人员的伙伴。它是一个包含各种类型列表的集合,这些列表在安全评估过程中经常使用,都在一个地方。SecLists通过方便地提供安全测试人员可能需要的所有列表,帮助提高安全测试的效率和生产力。列表类型包括用户名、密码、URL、模糊测试有效载荷、敏感数据模式、Web shell等等。测试人员只需将此存储库拉到新的测试机上,他就可以访问到所需的每种类型的列表。

禅工作室 13.0.1

禅工作室 13.0.1

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

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版