【问题标题】:Doctrine 2 : Page, Block, Strategy pattern & related entity原则 2:页面、块、策略模式和相关实体
【发布时间】:2012-05-04 23:42:21
【问题描述】:

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

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

因此,我想创建一个其他侦听器来监视相关实体的删除并删除该侦听器中的引用块。

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

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

【问题讨论】:

    标签: php doctrine-orm block strategy-pattern


    【解决方案1】:

    我不确定我是否理解你的问题,但如果你想要在实体中拥有实体并在删除父亲时删除子实体,你也可以将实体视为一个块并使用 Composite模式。

    您基本上可以在实体和块上使用相同的界面,并且在实体上的显示功能可能是这样的:

    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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-18
      • 2016-07-14
      • 2012-05-13
      • 2010-10-22
      • 1970-01-01
      • 1970-01-01
      • 2023-03-17
      相关资源
      最近更新 更多