My problem is exactly that described in the Strategy Pattern article in Doctrine documentation :
我的问题正是Doctrine文档中的策略模式文章中描述的问题:
- A Page entity
- 页面实体
- A page can have some blocks
- 页面可以有一些块
- A block might be a text, an image, a form, a calendar, ... (strategy)
- 块可能是文本,图像,表单,日历......(策略)
- A page knows about blocks it contains, but doesn't know about their behaviours
- 页面知道它包含的块,但不知道它们的行为
- Block inheritance is not possible
- 块继承是不可能的
Described solution (Strategy pattern) seems exactly what I need (read article for further information) :
所描述的解决方案(策略模式)似乎正是我所需要的(阅读文章以获取更多信息):
Page:
页:
<?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;
// ...
}
Block:
块:
<?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;
// ...
}
Strategy interface:
战略界面:
<?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();
}
I can easily imagine what would be my strategy if I would display a form or a calendar; but what if my strategy is to display content of an other entity ?
如果我要显示表格或日历,我可以很容易地想象出我的策略是什么。但是,如果我的策略是显示其他实体的内容呢?
The block needs to know about entity class/id and has to be deleted when related entity is removed.
块需要知道实体类/ id,并且在删除相关实体时必须删除。
I imagined to add entityClass
and entityId
properties in Block and load related entity on the postLoad event in a BlockListener. But what if related entity doesn't exist ? I can't remove the block in postLoad.
我想在块中添加entityClass和entityId属性并在BlockListener中的postLoad事件上加载相关实体。但是如果相关实体不存在呢?我无法删除postLoad中的块。
So, I imagined to create an other listener watching for removal of related entity and remove refering Block in that listener.
因此,我想象创建另一个监听器来监视删除相关实体并删除该侦听器中的引用块。
But it means that I need to add a listener for every entity that can be put in a block.
但这意味着我需要为每个可以放入块的实体添加一个监听器。
It could work, but it seems very complicated... maybe someone has a better idea ?
它可以工作,但似乎很复杂......也许有人有更好的主意?
1 个解决方案
#1
0
I'm not sure if I understood well your question, but if what you want is to have entities inside entities and delete the child entities when the father is deleted, you could also treat the entity as a block and use a Composite pattern.
我不确定我是否理解你的问题,但如果你想要的是在实体内部拥有实体并在删除父亲时删除子实体,你也可以将实体视为一个块并使用复合模式。
You basically could use the same interface on the entity and the blocks, and on the entity the display function could be something like:
您基本上可以在实体和块上使用相同的接口,并且在实体上,显示功能可以是:
foreach ($block in $blocks) {
$block->display();
}
For deleting all the children when you delete the parent entity, you could simply do it on the destructor of the entity.
要删除父实体时删除所有子项,只需在实体的析构函数上执行。
function __destruct() {
foreach ($block in $blocks) {
/* call a common interface function that does all that need to be done, implemented on each block */
}
}
For more on Composite pattern: http://en.wikipedia.org/wiki/Composite_pattern
有关复合模式的更多信息:http://en.wikipedia.org/wiki/Composite_pattern
#1
0
I'm not sure if I understood well your question, but if what you want is to have entities inside entities and delete the child entities when the father is deleted, you could also treat the entity as a block and use a Composite pattern.
我不确定我是否理解你的问题,但如果你想要的是在实体内部拥有实体并在删除父亲时删除子实体,你也可以将实体视为一个块并使用复合模式。
You basically could use the same interface on the entity and the blocks, and on the entity the display function could be something like:
您基本上可以在实体和块上使用相同的接口,并且在实体上,显示功能可以是:
foreach ($block in $blocks) {
$block->display();
}
For deleting all the children when you delete the parent entity, you could simply do it on the destructor of the entity.
要删除父实体时删除所有子项,只需在实体的析构函数上执行。
function __destruct() {
foreach ($block in $blocks) {
/* call a common interface function that does all that need to be done, implemented on each block */
}
}
For more on Composite pattern: http://en.wikipedia.org/wiki/Composite_pattern
有关复合模式的更多信息:http://en.wikipedia.org/wiki/Composite_pattern