gpt4 book ai didi

php - 拆分一个Symfony 2项目?

转载 作者:行者123 更新时间:2023-12-02 01:31:51 24 4
gpt4 key购买 nike

我们有一个非常大的Symfony 2 Web应用程序,它具有许多不同的端点和功能:

  • api,用于从我们的旧产品
  • 中获取数据
    用于我们的旧产品的
  • Web组件
  • api到我们新的iOS POS
  • 忠诚度最终用户门户
  • api
  • 忠诚度最终用户门户网站Web界面
  • (单独)发票最终用户门户网站
  • Web界面
  • 大管理区域,上面所有
  • 的配置

    数据库层(在Doctrine中)紧密耦合。忠诚度最终用户门户网站使用POS和我们的传统产品进行的交易,发票基于相同的交易。显然,还有许多实体仅用于应用程序的特定部分。

    我们最初决定采用单一应用程序+ bundle 方法来简化编程,这对于我们开发整个平台非常有帮助。不幸的是,主要缺点是:
  • 的性能非常差(尽管诸如进一步缓存,最小化资产等可以有所帮助,但我们认为拥有这样一个think肿的 bundle 包需要能够处理所有内容,并且还包括仅在应用程序的特定部分使用的不同的第三方库,放慢一切。)
  • 我们使用持续集成并生成新版本,并且运行所有功能测试都需要20多分钟的时间..并且我们仍然有很多类缺少(适当)测试。
  • 当我们更改应用程序的一部分时,另一部分很容易损坏。尽管越来越多的去耦和功能测试对此有所帮助,但这仍然远非理想。

  • 我已经进行了一些研究,将Symfony项目拆分为多个项目(每个项目都有自己的github),并使用SOA进行连接。到目前为止,我在SOA方面的个人经验是,从标准的Symfony 2格式(我完全喜欢)进行迁移时,它使事情变得很难完全测试,并且增加了很多开销。

    我也在考虑通过创建具有共享实体和存储库的共享 bundle 包的另一种解决方案。尽管我也听到反对大型经理的争论,但这将使测试代码和共享通用服务(经理)变得更加容易。最大的缺点是我们不能简单地使用doctrine:schema:update然后,因为在具有较低版本的共享包的项目上共享数据库并更新该数据库将删除字段,从而导致数据丢失。同样在这种方法下,我无法找到任何示例或用例..这使我想知道它是否没有更多的缺点。

    所以我的问题是:拆分这样一个大项目的通用方法和解决方案是什么?并且:是否有理由完全不应拆分?

    最佳答案

    尽管我正在回答您的问题,但是很难为您的问题提供神奇的解决方案。这不是解决所有问题的尝试,也不是强迫您遵循它。这不是唯一可能的解决方案,实际上这甚至可能无法解决您的问题。就是说,让我们开始吧。

    我将项目分为4层:

  • 表示层:桌面应用程序,Web界面(无论是否
    是php,C#,如果它使用Symphony或任何其他框架,第三个
    库组件),移动应用,最终用户可以看到的所有内容以及
    与(也称为GUI)进行交互。这些家伙只与
    应用程序/服务请求某些内容,例如可用列表
    产品,在某处更新一些数据,向客户发送电子邮件。
    这里的关键是他们真的不知道怎么去哪里
    应用程序/服务层将执行请求的操作。
  • 应用程序/服务层:我将其视为可以接收来自Presentation Layer和外部Web服务的请求的 Controller 。它们看起来像API,并且将决定是否必须通过Repository访问/处理数据或使用某些SMPT服务发送电子邮件。它们只是在GUI或可能使用您的API和域/基础架构层的外部Web服务之间进行通信。但是他们实际上并不知道他们正在使用什么SMPT服务,或者将数据存储在何处以及如何存储(在MySql中通过Doctrine?在Sql Server中通过Entity Framework?在NoSql数据库中?在txt文件中?)。应用程序层通常具有自己的模型(也称为ViewModels),这些模型向世人展示并返回给请求者(GUI或外部Webservice),表示域模型的部分。可以使用Facade和Adapters(也称为反腐败层)之类的模式来完成这种映射(将Domain类转换为Application类),并且有很多程序包可以解决此问题(对于C#,有Automapper,对于PHP,可能存在的东西)。你为什么需要这个?为了避免将您的完整域名暴露给全世界。假设您有发票和忠诚度最终用户,但您想将它们视为一个唯一的域类“用户”及其相应的属性。您可以在应用程序中创建LoyaltyUser和InvoiceUser类,每个类仅包含用于此目的的必要属性,然后使用此Mapping技术将域User类映射到它们中的每个。因此,应用程序层通常包含身份验证和授权规则,因此只有Loyalty最终用户才有权访问将处理LoyaltyUser模型的 Controller 操作。在 Controller 中的单个动作中,您不应根据请求者采取不同的路径/方式(对于移动设备,请执行此操作,对于网站,请执行此操作)。取而代之的是,每个动作可能有不同的动作,并且Presentation图层知道他们要请求的内容。
  • 域层:这是您的核心,包含所有业务逻辑。这就是为您的业务提供价值的要素。域层容器
    代表您世界中真实实体的模型/类,界面
    用于服务和存储库。域必须是最干净的
    自然可能。他们不知道什么应用程序在问
    某些东西,也没有如何使用红外线的类型。他们只是做生意
    逻辑。域层不知道您是使用Doctrine还是Laravel作为ORM,也不知道该应用程序是使用Symphony完成的php网站还是Android Native App。
  • 基础层:在这里,您可以实现数据库,SMPT服务,日志记录以及应用程序可能需要的其他东西。
    教义将居住在这里。因此,您将创建存储库
    类实现您域的存储库接口(interface)。的
    仓库实现使用Doctrine来完成工作。这些
    实现提供给应用层(通常通过
    依赖注入(inject))。这意味着应用层不应该
    知道是Doctrine还是Laravel,这就是为什么应用程序使用
    存储库(因此访问数据库的逻辑已封装)。

  • 您的Web界面将驻留在Presentation中。如果您在Web中使用的框架必须使用MVC并因此具有 Controller ,则这些 Controller 应调度到应用程序层(我知道这听起来很多余)。您的API将驻留在应用程序层中。

    这是非常分离的,如果您需要从Doctrine更改为Laravel,则无需更改您的Domain或Apps。如果您需要从Symphony更改为其他任何内容,或者甚至将您的网站从PHP更改为ASP或Java,则无需更改您的域。

    考虑到当今硬件的价格和容量,使用DI添加更多的层,映射对象,使用DI不应使请求变慢,几乎看不到时间上的差异。您应该努力改善自己的领域,为企业带来价值。分离各层可改善去耦,改变应用程序的一部分破坏其他部分的机会,增加应用程序扩展的灵活性,并使测试更加容易。

    关于php - 拆分一个Symfony 2项目?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33740905/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com