cube/doctrine-entity-factory

该包已废弃,不再维护。未建议替代包。

提供使用工厂模式进行Doctrine实体构建的接口

1.0.0 2016-08-18 12:17 UTC

This package is not auto-updated.

Last update: 2023-04-18 07:55:17 UTC


README

Build Status Code Coverage Packagist Author License

用于创建新的Doctrine实体的工厂模式。自Doctrine 2.0起,实体可以创建使用构造函数。为了创建一个可以在实现Doctrine的库之间实现的通用工厂模式,该存储库提供了一个接口,用于工厂创建一个要持久化到对象管理器的实体。

安装

此模块的安装使用composer。有关composer文档,请参阅getcomposer.org

$ php composer.phar require cube/doctrine-entity-factory

此解决方案解决了什么问题?

假设你有一个类,在某个时刻需要实例化一个新的Doctrine实体。zfcampus/zf-apigility-admin项目中的DoctrineResource是一个很好的例子,以下是简化后的代码:

class DoctrineResource 
{
  public function create($data)
  {
    $entityClass = $this->getEntityClass();
    // ...
    $entity = new $entityClass(); // notice this line
    // ...
    return $entity;
  }
}

上述代码的问题在于,用户不能实例化任何在构造函数中需要参数的实体。如果他们想使用命名构造函数来实例化对象,他们也不能这样做。实体构造函数中有必要参数可能有多种原因,但既然Doctrine允许这样做,那么你也应该允许。此外,在上述示例中,DoctrineResource充当实体的实际工厂,这对该类来说是一个过多的责任。

解决方案是将用户Doctrine实体的实例化与你的库解耦。因此,我们创建了一个接口,EntityFactoryInterface,它可以由任何需要Doctrine实体新实例的库使用,但想要委托构建该实体的过程。你的更新后的类如下所示

use Cube\DoctrineEntityFactory\EntityFactoryInterface;
class DoctrineResource 
{
  /** 
    * @var EntityFactoryInterface Set e.g. via DI, can default to SimpleEntityFactory
    *                             to avoid BC breaks 
    */
  private $entityFactory; 
  
  public function create($data)
  {
    $entityClass = $this->getEntityClass();
    // ...
    $entity = $this->entityFactory->get($entityClass); 
    // ...
    return $entity;
  }
}

现在你的类实际上不需要实例化Doctrine实体!

又一个库(翻个白眼)?

是的,因为上述用例实际上在几个Doctrine库中相当常见。通过提供集中的接口,我们可以让所有这些其他库委托实例化到相同类型的工厂。

此库还提供了两个简单的实现

  • SimpleEntityFactory:与执行new $entityClass的SOLID等效
  • BypassConstructorEntityFactory:将使用反射完全绕过构造函数来构建实体。

其他实现是可能的,最常见的情况可能是了解如何很好地实例化其实体的最终用户工厂。

这个库适合我吗?

如果你正在分发需要Doctrine实体新实例的代码,但你个人没有(或不想!)了解或控制该实体如何被实例化,那么这个库适合你。

许可

LICENSE.md