我的问题正是Strategy Pattern article in Doctrine documentation中描述的问题:
描述的解决方案(战略模式)似乎正是我所需要的(阅读文章以获取更多信息):
页:
<?php
namespace Page\Entity;
class Page
{
/**
* @var int
* @Id @GeneratedValue
* @Column(type="integer")
*/
protected $id;
/**
* @var string
* @Column
*/
protected $title;
/**
* @var string
* @Column(type="text")
*/
protected $body;
/**
* @var Collection
* @OneToMany(targetEntity="Block", mappedBy="page")
*/
protected $blocks;
// ...
}
块:
<?php
namespace Page\Entity;
class Block
{
/**
* @Id @GeneratedValue
* @Column(type="integer")
*/
protected $id;
/**
* @ManyToOne(targetEntity="Page", inversedBy="blocks")
*/
protected $page;
/**
* @Column
*/
protected $strategyClass;
/**
* Strategy object is instancied on postLoad by the BlockListener
*
* @var BlockStrategyInterface
*/
protected $strategyInstance;
// ...
}
策略界面:
<?php
namespace Page\BlockStrategy;
interface BlockStrategyInterface
{
public function setView($view);
public function getView();
public function setBlock(Block $block);
public function getBlock();
public function renderFrontend();
public function renderBackend();
}
如果我要显示表格或日历,我可以很容易地想象出我的策略是什么。 但是,如果我的策略是显示其他实体的内容呢?
块需要知道实体类/ id,并且在删除相关实体时必须删除。
我想在块中添加entityClass
和entityId
属性,并在BlockListener中的postLoad事件中加载相关实体。
但是如果相关实体不存在呢?我无法删除postLoad中的块。
所以,我想创建另一个监听器来监视删除相关实体并删除该侦听器中的Block。
但这意味着我需要为每个可以放入块的实体添加一个监听器。
它可以工作,但看起来很复杂......也许有人有更好的主意?
答案 0 :(得分:0)
我不确定我是否理解你的问题,但如果你想要的是在实体内部拥有实体并在删除父亲时删除子实体,你也可以将实体视为一个块并使用复合图案。
你基本上可以在实体和块上使用相同的接口,在实体上显示功能可以是这样的:
foreach ($block in $blocks) {
$block->display();
}
删除父实体时删除所有子节点,只需在实体的析构函数上执行即可。
function __destruct() {
foreach ($block in $blocks) {
/* call a common interface function that does all that need to be done, implemented on each block */
}
}
有关复合图案的更多信息: http://en.wikipedia.org/wiki/Composite_pattern