我有主要实体
/**
* @ORM\Entity()
*/
class Document
{
/**
* @var int
* @ORM\Id()
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var DocumentStatus
* @ORM\ManyToOne(targetEntity="DocumentStatus")
*/
private $status;
/**
* @var string
* @ORM\Column(type="text")
*/
private $text;
}
和查找"枚举"实体(在应用程序部署上播种)
/**
* @ORM\Entity(repositoryClass="DocumentStatusRepository");
*/
class DocumentStatus
{
const DRAFT = 'draft';
const PENDING = 'pending';
const APPROVED = 'approved';
const DECLINED = 'declined';
/**
* @var int Surrogate primary key
* @ORM\Id()
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string Natural primary key (name for developers)
* @ORM\Column(type="string", unique=true)
*/
private $key;
/**
* @var string Short name for users
* @ORM\Column(type="string", unique=true)
*/
private $name;
/**
* @var string Full decription for users
* @ORM\Column(type="string", nullable=true, unique=true)
*/
private $description;
}
使用简单的存储库
class DocumentStatusRepository extends EntityRepository
{
public function findOneByKey($key)
{
return parent::findOneBy(['key' => $key]);
}
}
我想通过引入类似
的方法来封装文档生命周期的域逻辑public function __construct($text)
{
$this->text = $text;
$this->status = $something->getByKey(DocumentStatus::DRAFT);
}
public function approve()
{
try {
$this->doSomeDomainActions();
$this->status = $something->getByKey(DocumentSatus::DRAFT);
} catch (SomeDomainException($e)) {
throw new DocumentApproveException($e);
}
}
...
或
public function __construct($text)
{
$this->text = $text;
$this->status = $something->getDraftDocumentStatus()
}
public function approve()
{
$this->status = $something->getApprovedDocumentStatus()
}
...
没有公共制定者。另外,我希望保持文档松散耦合和可测试。
我看到了下一个方法:
还有其他方法吗?从长远来看,哪种方式更容易使用?
答案 0 :(得分:1)
使用生成的文件身份。
现在,您将在数据库一侧生成标识。所以你save
从域角度看文档处于不一致状态。实体/汇总should be identified
,如果它没有ID,则它不应该存在。
如果您真的想要保留数据库连续出版物,请将方法添加到存储库,该方法将为您生成id
更好的方法是使用uuid生成器,例如ramsey / uuid。
inject
身份to the constructor
。
DocumentStatus
作为价值对象
为什么文档状态是实体?它看起来像一个简单的值对象。
然后你可以使用Embeddable注释。因此它将留在数据库中的同一个表中,不需要进行内部连接
DocumentStatus获取行为,例如 - > draftDocumentStatus(),returns NEW DocumentStatus
具有草稿状态,因此您可以使用新实例切换旧实例。 ORM将完成剩下的工作。
DocumentStatusRepository
如果你真的想把DocumentStatus保留为实体,我认为is wrong
你不应该有DocumentStatusRepository。
Document是您的聚合根,而DocumentStatus的only entrance
应该是聚合根
因此,您将只拥有DocumentRepository,它将负责rebuilding
整个聚合和saving
它。
你也应该改变映射
它应该具有FETCH=EAGER
类型,因此它将与Document一起检索DocumentStatus
其次,您应该使用CASCADE=ALL
和ORPHANREMOVAL=TRUE
进行制图
否则,如果您remove
文档,DocumentStatus will stay in the database
。