Symfony项目设计模式

时间:2016-05-11 05:54:21

标签: php symfony oop design-patterns

symfony 2安装程序提供了最佳实践目录结构,但没有说明如何使用这些目录,每个代码片段属于哪里,确保symfony框架将其缩小到视图,实体和控制器,服务等等,但更常见的是,程序员最终在控制器中放置一个DQL查询和一些处理特定任务的逻辑,虽然这样做,但必须有一个更好的方法,甚至超出symfony的范围。盒子目录结构,目前正在寻求更好的设计模式,尽可能模块化和重用

在这个任务中,在interwebz上发现了几篇好文章,并花了一天时间,提出了一个计划,将所有数据库交互分离到存储库,所有逻辑服务,并保持控制器“瘦”和#39;它充当从存储库和调用服务调用方法的中心点。听起来不错,将是模块化的,代码可以重复使用....但是

这种方式从OOP概念转向程序化编程,而不是它有任何问题,它只是没有利用OOP的强大概念

可以让对象变得更强大'通过添加更多功能使其更好?根据定义,服务应该是一个单元的任务,我的方法会使它们变得大而丑陋

此博客上的一些优点here但无法确定他们试图建议的解决方案

  

通常,您在服务中找到的行为越多,就越多   可能你要剥夺自己域名的好处   模型。如果您的所有逻辑都在服务中,那么您就会失明     -Martin Fowler

总结是面向服务的方法而不是利用OOP的概念?如何补充

3 个答案:

答案 0 :(得分:8)

您可以在Fowler的“企业应用程序架构模式”中找到的最重要的想法之一是,您应该使用正确的工具来完成工作。根据您的问题和域的复杂性,一个或另一个设计模式/架构模式可能会表现得更好。遵循这种方式,与旧框架(ZF1,SF1)相比,SF2 +不会强迫您使用任何架构模式或以特定方式组织业务逻辑。你甚至可以把所有东西都放在捆绑结构之外。因此,您可以做的最好的事情是尝试更多地了解设计模式(通常)。然后,当您需要时,您将能够选择最适合您案例的那个。

您可能需要查看:

答案 1 :(得分:1)

首先,有一些放置文件/组件的最佳做法:http://symfony.com/doc/current/cookbook/bundles/best_practices.html

其次http://symfony.com/doc/current/best_practices/business-logic.html

  

在Symfony应用程序中,业务逻辑是您为应用程序编写的所有自定义代码,并非特定于框架(例如路由和控制器)。用作服务的域类,Doctrine实体和常规PHP类是业务逻辑的良好示例。

因此,您不必为业务逻辑使用任何架构。

关于您的问题 - 您可以使用操作实现对象并将它们声明为服务(或直接使用它们,但在这种情况下,当您想要替换某些功能时,您需要重新编写更多代码)。

  • 软件设计总是有很多原则,我们选择我们认为更正确的东西,对项目更有意义,Symfony不会强迫我们使用某种特殊的设计模式。

答案 2 :(得分:1)

使用Domain Driven Design,它可以创建胖模型层,并且在控制器内调用很多服务可能会模块化你的代码,它仍然有自己的一系列挑战,它使设计更难创建,并且在某些时候出现将在控制器内部进行过多的服务调用,实际可以做的是使用DDD中的一些概念。

在启动DDD之前要记住的两件事是: -

  1. 凝聚力 - 一起变化的模块
  2. 耦合 - 彼此依赖的模块
  3. 您需要减少耦合并识别内聚并根据它设计项目,主要目标是允许在将来添加和删除或启用/禁用/重新组合模块,以防您决定更改项目

    而不是让bundle依赖于彼此使用接口而不是

    namespace MyProject\UserBundle\Activity ;
    
    use MyProject\NotificationBundle\Notification;
    use MyProject\MailBundle\Mail;
    

    其中UserBundle与NotificationBundle和MailBundle结合使用抽象捆绑包的接口

    namespace MyProject\UserBundle\Activity ;
    
    use MyProject\ServiceBundle\NotificationInterface;
    use MyProject\ServiceBundle\MailInterface;
    

    DDD的主要概念是

    1. 值对象 - 一个包含一些数据并且来回传递的对象,聚焦身份,而不是它所拥有的数据,值对象可以是使用embeddables
    2. 在symfony中使用
    3. 实体 - 包含某些数据但依赖于身份值而非其数据值的对象
    4. 存储库 - 使用存储库类进行数据库操作可以在以后更改实现,因为它集中在一个地方
    5. 聚合 - 当多个对象属于一个属于单个类别的一些事物(例如:属于某个类型的歌曲)时,整个对象集合被视为一个对象在单个聚合对象
    6. 上会考虑对这些对象进行更改
    7. 域事件 - 域/数据状态的任何变化都被视为一个事件,在symfony中有事件监听器和订阅者可以代表域事件,这是其中之一最重要的DDD概念,过滤器也对代码进行了大量改进
    8. 服务 - 服务是可调用的代码模块,用于执行工作单元,服务允许重用代码并且更易于测试和更新,symfony中的服务应包含域逻辑和服务图层可以变得非常胖,这与事件使代码更快,更易于维护
    9. 工厂模式 - 此模式使用生成不同对象的“工厂”对象,通过这样做抽象出第二个对象的名称,这有助于重构代码
    10. 这些是需要应用于高度情境化代码的通用概念,正确的DDD要求代码是模块化的,这是一项具有挑战性的任务,需要一些工程师的经验。

      正如其他人已经说过的那样,“马丁福勒”,“V.Vernon”设计模式中的“四人帮”等书籍将是一个很好的阅读