设计模式Doctrine ORM - 根据输入

时间:2016-02-13 18:06:18

标签: php entity-framework symfony orm doctrine

我正在使用Symfony2和Doctrine ORM,希望以干净的架构实现以下目标:

每次创建新实体时,我都希望保存最终用户选择的“显示名称”,然后根据“显示名称”生成“唯一名称”。

如果我的最终用户想要创建名为“图纸”的3个项目,

  • 第一个将具有display_name =“drawings”
  • 第二个将具有display_name =“drawings2”
  • 第三个将具有display_name =“drawings3”

(或类似的东西,无论模式如何)

基本实体示例:

/**
 * Project.
 *
 * @ORM\Entity
 */
class Project
{
    //...

    /**
     * @ORM\Column(type="string", length=50, nullable=false)
     */
    protected $name_display ;

    /**
     * @ORM\Column(type="string", length=50, nullable=false, unique=true)
     */
    protected $name_unique ;

    //...

基本用法示例:

$project = new Project();
$project->setDisplayName('Drawings'); 
//Around here I would like the Unique name to be generated
$this->getDoctrine()->getManager()->persist($project);

我想到了各种解决方案:

  • 在Controller中进行名称生成,但不可重复使用
  • 在存储库中执行唯一名称生成。但它看起来很糟糕(存储库应该是只读的)
  • 使用PrePersist LifecycleCallbacks from the doctrine,但这不是一个好习惯,因为我需要Entity Manager来做数据库
  • 在Entity Setter中执行名称生成,注入实体管理器以发出请求并查找可用名称。那看起来很可怕
  • 使用服务来保存实体,如下所述:Are Doctrine2 repositories a good place to save my entities?(但是如果我希望我的所有实体创作与此实践保持一致,那么它非常复杂并且涉及我的基础架构的巨大变化)

1 个答案:

答案 0 :(得分:1)

我会推荐最后的选项 - 服务。它可能需要对您的项目进行更改,但我发现这是使用实体管理通常的crud操作的最佳方法 - 创建,保存,findBySomething ......

  • 很清楚 - 没有黑魔法。与已执行的代码与实体的操作之间没有明显关系的事件相反(例如通过new创建它)。
  • 它不依赖于注释,而且易于维护。
  • 控制器和其他服务可以通过依赖注入访问此服务,这是一种满足业务对象(包含业务逻辑的对象)依赖关系的明确方法。
  • 您的存储库不会变得越来越大
  • 您可以使用默认存储库 - 升级Doctrine
  • 时背面兼容性问题更少
  • 它比" setter解决方案"好得多,听起来真的太可怕了 - 实体永远不会那么强大,所以他们会引用服务(特别是像EntityManager这样的服务)