PHP 回调与模板

发布于 2024-11-26 02:09:15 字数 1952 浏览 0 评论 0原文

我构建了一个列表渲染类:

class ListRenderer
{
    /**
     * @param int $columns number of columns
     * @param string $element container element
     * @param string $styleClass container style
     */
    public function __construct($columns,$element='div',$styleClass=''){...}
    ...
    /**
     * @param mixed $callback function to render items - should take two
     *        parameters ($item,$index)
     * @param array $list items to render
     */
    public function renderArrayList($callback,$list){...}

    /**
     * @param mixed $callback function to render items - should take 3 parameters
     *        ($row,$i,$count) $i and $count are the position and total items
     * @param string $sql query string
     * @param string $errorMessage
     * @param int $blanks number of blank items to render. The callback will be
     *        invoked with a null $row parameter for the blank records.
     */
    public function renderQueryList($callback,$sql,$errorMessage,$blanks=0){...}
    ...
}

回调函数渲染单个项目。

这也可以使用模板来完成:

class ListRenderer
{
    ...
    //$itemRenderer implements ListItemRenderer
    public function renderArrayList($itemRenderer,$list){...}
    //$itemRenderer implements ListItemRenderer
    public function renderQueryList($itemRenderer,$sql,$errorMessage,$blanks=0){...}
    ...
}

template ListItemRenderer
{
    public function renderArrayItem($item,$index);
    public function renderQueryItem($row,$index,$count);
}

class SomeClass implements ListItemRenderer
{
    ...
    public function renderArrayItem($item,$index){...}
    public function renderQueryItem($row,$index,$count){...}
    ...
}

我不确定为什么我要在这个模板上使用回调;来自 Java 背景的我通常倾向于使用第二种方法。

在我看来:

  • 回调更灵活
    • 模板会将单个类限制为一个 renderArrayItem 函数,例如,回调将允许每个类为此目的使用多个函数。
    • 模板方法要求函数是类成员。
  • 回调往往会产生不易维护的代码。

是否有充分的理由在这方面采取一种或另一种方式?

I've built a list rendering class:

class ListRenderer
{
    /**
     * @param int $columns number of columns
     * @param string $element container element
     * @param string $styleClass container style
     */
    public function __construct($columns,$element='div',$styleClass=''){...}
    ...
    /**
     * @param mixed $callback function to render items - should take two
     *        parameters ($item,$index)
     * @param array $list items to render
     */
    public function renderArrayList($callback,$list){...}

    /**
     * @param mixed $callback function to render items - should take 3 parameters
     *        ($row,$i,$count) $i and $count are the position and total items
     * @param string $sql query string
     * @param string $errorMessage
     * @param int $blanks number of blank items to render. The callback will be
     *        invoked with a null $row parameter for the blank records.
     */
    public function renderQueryList($callback,$sql,$errorMessage,$blanks=0){...}
    ...
}

The callback function renders a single item.

This could also be accomplished using templates:

class ListRenderer
{
    ...
    //$itemRenderer implements ListItemRenderer
    public function renderArrayList($itemRenderer,$list){...}
    //$itemRenderer implements ListItemRenderer
    public function renderQueryList($itemRenderer,$sql,$errorMessage,$blanks=0){...}
    ...
}

template ListItemRenderer
{
    public function renderArrayItem($item,$index);
    public function renderQueryItem($row,$index,$count);
}

class SomeClass implements ListItemRenderer
{
    ...
    public function renderArrayItem($item,$index){...}
    public function renderQueryItem($row,$index,$count){...}
    ...
}

I'm not sure why I went with callbacks on this one; coming from a Java background I would normally be inclined to use the second approach.

It seems to me that:

  • Callbacks are more flexible
    • Templates would limit a single class to one renderArrayItem function, for example, where callbacks would allow use of multiple functions per class for that purpose.
    • The template approach requires the function to be a class member.
  • Callbacks tend to produce less maintainable code.

Are there any strong reasons to go one way or the other on this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

青春有你 2024-12-03 02:09:15

造成这种情况的原因可能有多种,反之亦然。特别是对于你的情况,我不知道有什么区别,因为我不知道你的应用程序。

所以我反问:为什么一个与另一个相对?如果您仍然不知道该走哪条路,或者不确定您是否明确想要其中一种,为什么不制作一个可以在需要时使用的回调变体呢?您可以在实例化类时注入回调:

class ListItemCallbackRenderer implements ListItemRenderer
{
    private $callbacks;
    public function __construct(array $callbacks)
    {
        $this->callbacks = $callbacks;
    }
    public function renderArrayItem($item,$index)
    {
        $callback = $this->callbacks[__FUNCTION__];
        // ...
    }
    public function renderQueryItem($row,$index,$count)
    {
        $callback = $this->callbacks[__FUNCTION__];
        // ...
    }
}

完成此操作后,界面保持不变,这使您的整体设计更加流畅,并且您可以决定在应用程序中的各处使用哪个变体。实际上没有必要将自己降级为一种方法。

There can be multiple reasons for the one versus the other and the other way round. Especially for your case I have no clue what the difference is because I don't know your application.

So I ask back: Why one versus the other? If you still don't know which way to go, or unsure if you want the one or the other explicitly, why don't you make a callback variant you can use when needed? You can inject the callbacks when instantiating the class:

class ListItemCallbackRenderer implements ListItemRenderer
{
    private $callbacks;
    public function __construct(array $callbacks)
    {
        $this->callbacks = $callbacks;
    }
    public function renderArrayItem($item,$index)
    {
        $callback = $this->callbacks[__FUNCTION__];
        // ...
    }
    public function renderQueryItem($row,$index,$count)
    {
        $callback = $this->callbacks[__FUNCTION__];
        // ...
    }
}

Done this, the interface stays the same which makes your overall design more fluid and you can decide which variant to use everywhere in your application. No need to degrade yourself to one method actually.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文