【问题标题】:Symfony project design patternSymfony 项目设计模式
【发布时间】:2016-05-11 05:54:20
【问题描述】:

symfony 2 安装程序提供了一个最佳实践目录结构,但没有太多说明应该如何使用这些目录,每段代码属于哪里,确保 symfony 框架将其缩小到视图、实体和控制器,服务等,但更多时候不是,程序员最终将 DQL 查询放入控制器和一些逻辑来处理特定任务,虽然这可以完成工作,但必须有更好的方法,甚至超出 symfony 的开箱即用目​​录结构,目前正在寻求更好的设计模式,尽可能地模块化和重用

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

这以某种方式从 OOP 概念转移到过程编程中,并不是说它有什么问题,只是没有利用 OOP 的强大概念

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

此博客 here 上的一些优点,但无法真正弄清楚他们试图提出的解决方案是什么

一般来说,您在服务中发现的行为越多, 您可能会剥夺自己的域名优势 模型。如果您所有的逻辑都在服务中,那么您已经蒙蔽了自己 -马丁·福勒

总结面向服务的方法是否没有利用 OOP 的概念?以及如何补充这一点

【问题讨论】:

  • 您想回答哪些问题?现在你的问题对我来说太宽泛了。
  • @xabbuh 我想了解更多关于 symfony 项目中的设计模式,面向服务的方法没有很好地利用 OOP 概念,可以做些什么来补充呢?我想设计我的项目以使用抽象和继承。我想知道这两者在哪里适合面向服务的方法
  • 我使用 symfony 是因为我认为它在各个方面都很完美

标签: php symfony oop design-patterns


【解决方案1】:

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

你可能想看看:

【讨论】:

  • 您好,谢谢您的回复,您能否也对您提到的资源做一个简短的总结?只是为了完成
  • 1up 的资源,会看看那些
【解决方案2】:

使用领域驱动设计,它会创建胖模型层,并且在控制器内部调用大量服务可能会模块化您的代码,它仍然有自己的一系列挑战,它使设计更难创建,并且在某些时候存在控制器内部的服务调用会太多,实际上可以做的是使用DDD中的一些概念。

在开始 DDD 之前要记住两件事:-

  1. 凝聚力 - 一起改变的模块
  2. 耦合 - 相互依赖的模块

您需要减少耦合并认识到内聚并根据它设计项目,主要目标是允许将来添加和删除或启用/禁用/重新组合模块,以防您决定更改项目

不要让捆绑包相互依赖,而是使用接口

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. 值对象 - 一个持有一些数据并来回传递的对象,它关注身份,而是关注它持有的数据,值对象可以在 symfony 中使用使用embeddables
  2. 实体 - 持有一些数据但依赖于标识值而不是其数据值的对象
  3. 存储库 - 使用存储库类进行数据库操作使得以后可以更改实现,因为它集中在一个地方
  4. 聚合 - 当多个对象像属于一个类别的多个事物一样属于同一类别时(例如:属于某个流派的歌曲),整个对象集合被视为一个对象并进行更改这些对象将被视为单个聚合对象
  5. 域事件 - 域/数据状态的任何变化都被视为一个事件,在 symfony 中有可以代表域事件的事件监听器和订阅者,这是最重要的概念之一DDD的,filter对代码也有很大的改进
  6. services - 服务是可调用的代码模块,完成一个工作单元,服务允许代码被重用并且更容易测试和更新,symfony 中的服务应该包含领域逻辑并且服务层可以获取相当胖,这与事件一起使代码更快,更易于维护
  7. 工厂模式 - 这种模式使用“工厂”对象生成不同的对象,这样做可以抽象出第二个对象的名称,这有助于重构代码

这些是通用概念,需要应用于高度情景化的代码,正确的 DDD 要求代码是模块化的,这是一项具有挑战性的任务,并且需要工程师方面的一些经验。

正如其他人已经说过的,'martin fowler' 的书籍,'gang offour' 的'V.Vernon' 设计模式等将是一个很好的阅读

【讨论】:

    【解决方案3】:

    首先有放置文件/组件的最佳实践:http://symfony.com/doc/current/cookbook/bundles/best_practices.html

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

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

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-14
      • 1970-01-01
      • 2011-09-01
      • 2011-07-10
      • 2010-12-09
      • 1970-01-01
      • 1970-01-01
      • 2011-06-29
      相关资源
      最近更新 更多