在视图中使用getter方法是否是一个好的实践?

3

我有两张表:Campaigns和Campaign_statistics。我需要输出嵌套统计信息的广告系列列表。

首先,我在模型中创建了一个方法,生成如下数组:

array(
    'id', // integer
    'campaign_name',// string
    'stats'// nested array of arrays with stats by periods
);

在一个视图中,我有两个foreach循环(一个嵌套在另一个内部):
<? foreach ($this->campaigns as $campaign): ?>
    <div class="campaign">
        <?= $campaign['name'] ?>
        <? foreach($campaign['stats'] as $monthStats): ?>
            <div class="statistics">
                <?= $monthStats['views'] ?>
            </div>
        <? endforeach ?>
    </div>
<? endforeach ?>

那种模型实现方式会导致混乱的代码,因此我决定尝试将Campaign转化为对象。在视图中,我使用getter:

<? foreach($this->campaigns as $campaign): ?>
    <div class="campaign">
    <?= $campaign->getName() ?>
    <? foreach($campaign->getMonthStats() as $monthStats): ?>
        <div class="statistics">
            <?= $monthStats->getViews() ?>
        </div>
    <? endforeach ?>
    </div>
<? endforeach ?>

我从未见过任何框架像这样使用getter。这种方法有什么优缺点?

4个回答

4
在面向对象设计中,使用getter方法的好处在于它们隐藏了返回结果计算的复杂性。因此,你可以更改计算视图的方式,并自动更新所有应用程序。纯粹主义者认为,在视图中不应该有方法调用等,但像我这样的实用主义者认为,将方法调用放入视图中,因为可以对其进行单元测试。然而,当发现输出变得过于复杂时(Martin Fowler称之为对象过于亲密),则需要重构以使用单个方法调用。
底线是:方法很好,因为它们的输出可以被验证。

1
通常你不会看到显式的getter,而是人们访问属性。
但是这只适用于你的属性是公共的情况下。
在视图中实现Zend_Form,您可以使用getter和setter访问元素和其他属性。
我没有看到你所做的选择有任何主要问题。
然而,我可能会使用partialLoop()视图助手实现第二个foreach(),或者自己构建一个视图助手,特别是如果我打算在多个地方使用它。
//example of what is commonly seen...
<? foreach($this->campaigns as $campaign): ?>
    <div class="campaign">
    <?= $campaign->name ?>
    <? foreach($campaign->stats as $monthStats): ?>
        <div class="statistics">
            <?= $monthStats->views() ?>
        </div>
    <? endforeach ?>
    </div>
<? endforeach ?>

这只是我的个人意见,玩得开心。


1
我之前和同事们有过同样的争论,我不赞成在模板中使用方法。这会使模板不透明,没有清晰的了解模板内部可用的内容 - 你必须知道你所处理的对象和设计师,后来加入的开发人员不应该担心这个,他们只需要看到控制器中传递了什么。更不用说,在模板内部调用方法可能会改变已经传递的数据...虽然我知道在某些情况下,模板可以在循环或其他情况下进行更改,但我倾向于认为模板比其他代码更静态 - 对数组进行迭代不会改变任何其他数组。但是对于对象,我并不确定。
这还会增加重构的额外依赖。
它还会增加复杂性和诱惑力,让开发人员开始在模板中调用SQL或执行重型逻辑。
我可能还可以指出,简单的模板引擎往往是简单的文本替换器。而方法对它们来说不是一个选项。

我们正在谈论getter,而不是大型方法 :) 对于任何比getter更复杂的东西,我都同意你的看法。 - haltabush
1
没错。嗯,我只是害怕冒号:D 我想,如果你知道自己在做什么,玩一下铀也应该没事。 - Artjom Kurapov

0

听起来对我来说没问题 :)

例如,Magento也允许这样做。

无论如何,这更多是个人观点的问题...但我倾向于同意你的看法,这使得模型或控制器更易于阅读(不需要 $view->toto = $model->getToto())。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接