我有两个表:广告系列,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。这种方法的优缺点是什么?
答案 0 :(得分:4)
面向对象设计中吸气剂的美感在于它们隐藏了返回结果计算方式的复杂性。因此,您可以更改计算视图的方式,并在所有应用程序中自动更新。
纯粹主义者声称你不应该在视图等方面进行方法调用,但像我这样的实用主义者说,将方法调用放在视图中,因为方法可以进行单元测试。但是,当您发现输出变得过于复杂时(Martin Fowler称这些对象彼此过于亲密),那么您需要重构以使用单个方法调用。
结论:方法很好,因为可以验证其输出
答案 1 :(得分:1)
我之前和我的同事有过同样的争论,我不同意在模板中使用方法。这使得模板不透明,没有清楚知道模板内部可用的东西 - 你必须知道你处理的对象和设计师,以及后来加入的开发人员不应该担心,他们应该看到什么在控制器中传递就是这样。更不用说来自模板内部的方法调用可能会改变已经在里面传递的数据。虽然我知道在某些情况下它可以让模板在周期或其他方面发生变化,但我倾向于认为模板更加静态然后剩下的代码 - 迭代数组不会改变任何其他数组。但我不太确定对象。
它还为重构添加了额外的依赖性。
它还增加了开发人员开始调用SQL或在模板中执行重逻辑的复杂性和诱惑力。
我可能也指出简单的模板引擎往往是一个简单的文本替换者。并且方法不是他们的选择。
答案 2 :(得分: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 ?>
只是我的意见,玩得开心。
答案 3 :(得分:0)
对我来说听起来不错:) 例如,Magento允许相同的事情。
无论如何,这更多的是个人观点而不是任何事情...但我倾向于同意你,它使模型或控制器更容易阅读(不需要$ view-&gt; toto = $ model-&gt; getToto()