设计模式原则ORM - 根据输入生成唯一名称


Design pattern Doctrine ORM - Generate unique names based on input

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

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

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

  • 第一个将具有display_name="图纸">
  • 第二个将有 display_name = "图纸2">
  • 第三个将具有display_name = "图纸3">

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

基本实体示例:

/**
 * 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);

我想到了各种解决方案:

  • 在控制器中生成名称,但不可重用
  • 在存储库中生成唯一名称。但这似乎是一个糟糕的做法(存储库应该是只读的(
  • 使用预持久生命周期原则中的回调,但这不是一个好的做法,因为我需要实体管理器来做一个数据库
  • 在实体资源库中执行名称生成,注入实体管理器以发出请求并查找可用名称。这看起来很可怕
  • 使用服务来持久化实体,如下所述:Doctrine2 存储库是保存实体的好地方吗?(但是如果我想让我所有的实体创建都与这种做法保持一致,这非常复杂,并且涉及我的基础设施的巨大变化(

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

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