如何使用 symfony4 实现模块化架构

Erw*_*zel 5 architecture modular symfony4

我想遵循 Sander Mak 的这篇文章的建议,它提倡使用传统的单体架构,利用模块而不是微服务,这在许多情况下不是一个好的选择:https : //www.oreilly.com/ideas/模块与微服务

我对 Monolithic 与微服务进行了大量研究,得出相同的结论,即在许多情况下,Monolithic 仍然是最好的选择,并且可以以更简单的方式实现相同的目标。微服务应该在真正极端和特定的情况下使用。

当然,一个好的模块化架构的实现在每种语言和框架中都是不同的。作者正在谈论 Java 9 以及它如何完全重新定义实现这种模块化架构的方式。

但是 Symfony 4 呢?在第 4 版之前,似乎正确的方法是使用 Bundle。但是从第 4 版开始,官方文档明确建议不要再这样做了:https : //symfony.com/doc/current/bundles.html

在 4.0 之前的 Symfony 版本中,建议使用包来组织您自己的应用程序代码。不再推荐这样做,bundle 应该只用于在多个应用程序之间共享代码和功能。

但是我在文档中看不到现在正确的方法是什么!如果无法使用 Bundle,那么实现 Sander Mak 文章中定义的模块化架构的最佳实践是什么?

小智 4

我自己来自Java环境,但选择在SF4/PHP-7.x环境中编写我当前的应用程序。在 Laravel 5.x 之后,我选择 SF4 的原因有很多,这里要一一列举。

不要被 Symfony 4 和 5 的举动所困扰......我承认我并不总是理解他们所有的发展计划和营销策略,而且我在开始宣布新的无捆绑应用程序导向时感到沮丧。但本能地,也许是因为我没有其他选择,我努力尝试 SF4,并坚定地计划在 SF4 环境中强化我的应用程序模块化策略。

感谢 Sander Mak 关于模块与微服务的文章,它证实了我对模块化支持框架的需求,而不仅仅是微服务模块化功能。这里真正的重点是正确评估您想要作为模块实施的组织概念的类型和规模。模块化的微服务肯定可以用来实现复杂的硬件、业务活动和详细的组织基础设施。但成本高昂,并且需要大量资源来处理依赖性和相互联系。

对于 SF4,虽然他们通常谈论微内核,或构建自己的微服务框架,但我认为他们提供的产品是一个很好的整体平台,可以构建模块化业务应用程序。我承认与 java 环境相比,PHP OOP 的限制使得某些实现比预期更困难,但最终,对于常规业务应用程序需求,SF4 框架和组件提供了良好的应用程序基础。

在深入探讨使用 SF4 进行模块化应用程序开发的最佳方式之前,我将分享我对 SF4 领导者未来 2 年愿景/路线图的理解:

  • SF4 应用程序由 2 种互连的应用程序模块组成:Api 组件和 Bundle
  • Api-Component:(谷歌说)被定义为软件系统的模块化、可部署和可替换的部分,它封装其行为和数据并通过一组接口公开它们。这里最重要的事实是,API 组件必须实现通过 API 公开的所需(有边界的)业务功能。
  • Bundle :也是为 api 组件定义的组件,但粒度级别更高。这意味着,Bundle通常使用api组件(而不是逆向),并且主要面向User/Client可视化界面。将捆绑视为组织的小型应用程序、功能应用程序、部门级应用程序功能的实现。例如:AccountingBundle、InventoryBundle、ProcurementBundle ...粒度由每个设计团队自行决定。
  • 从 SF4 无捆绑包环境开始,Symfony 领导者决定放弃 AppBundle,因为根据经验,他们知道创建捆绑包与组件模块的开销。因此,“App”默认组件应用程序现在是为应用程序架构师提供多种解决方案的基础环境:

    1. “App”组件具有捆绑包的所有功能,编码较少,但它被视为中央 SF4 主模块。
    2. “应用程序”主模块可以与所有添加的模块组件和捆绑包共享应用程序配置、模板、资源
    3. 平台演进认为所提供的框架不需要了解太多关于添加的模块,并且默认的“应用程序”将是放置框架扩展的粘合剂的地方。
    4. 在他们看来,在“App”主模块、api 组件模块或捆绑包中实现功能现在是代码组织决策。
    5. 恕我直言,创建组件或捆绑包的决定都是由应用程序模块化要求定义的。因此,创建捆绑包或组件模块的决定主要不是由在公共空间/市场共享代码的需要驱动的,而是由设计干净的模块化、可维护、可重用代码的必要性驱动的。
    6. 因此,每一个将代码拆分为模块的决定都必须受到业务和技术要求的挑战。当您决定创建哪些模块时,在 SF4 中实现起来很容易。
  • 我对内部模块优先级的建议:

    1. 首先决定要创建哪些模块及其配置/参数要求。
    2. 利用 .env 环境实用程序的优势,将大多数配置/参数集中在“App”主模块中。
    3. 模块资源/翻译可以通过 2 个步骤创建:首先在主“应用程序”模块中进行快速、轻松的验证。然后,在第二步将它们移动到特定的捆绑包中......
    4. 所有其他模块使用的横向功能(例如安全性、配置和核心/公共服务)必须首先在“App”主模块中实现。随着经验的积累,一些功能可以在特色组件中重新组织,以实现更高的模块化和清晰度。
    5. 将包和 api 组件放在 /src 目录下,具有中央 Composer PSR-4 自动加载功能,并将它们从“App”services.yaml 中排除
    6. 请注意,在本建议中,我们不会过多地强化模块相对于“App”主模块的自主性。我们选择让它们在一开始就稍微依赖于中央模块配置功能。这是编码时间和验证的增益。随着开发人员在 SF4 编码规则方面获得更多经验,可以逐步加强模块封装。顺便说一句,第一个目标是及时交付应用程序。

当时间到来时,您想与社区共享特定模块,请检查将外部环境所需的最小配置/参数发送回该模块。