学说2:页面,块,策略模式&相关实体

时间:2012-04-24 10:30:54

标签: php doctrine-orm block strategy-pattern

我的问题正是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,并且在删除相关实体时必须删除。

我想在块中添加entityClassentityId属性,并在BlockListener中的postLoad事件中加载相关实体。 但是如果相关实体不存在呢?我无法删除postLoad中的块。

所以,我想创建另一个监听器来监视删除相关实体并删除该侦听器中的Block。

但这意味着我需要为每个可以放入块的实体添加一个监听器。

它可以工作,但看起来很复杂......也许有人有更好的主意?

1 个答案:

答案 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