我正试图绕过SPL迭代器,我想出了两种方法来处理它。我看到第一个版本不那么复杂,但第二个版本有它的构图感觉(我认为)。
我没看到的是哪一个优于另一个?或者我只是让这复杂化了?
以下是我的想法:
该对象实现了一个迭代器:
class BoxOfChocolates implements Iterator {
private $id
private $name; // e.g. Valentine's Heart Box
private $maker; // e.g. Hersheys
private $items; // array
public function getChocolates() {
$query = ...
foreach($rows as $row) {
$this->_items[] = new Chocolate() ...
}
}
// ... necessary iterator implementation stuff
}
该对象包含一个可迭代的对象:
class BoxOfChocolates {
private $id;
private $name;
private $maker;
private $items; // chocolates object
public function getChocolates() {
$this->items = new Chocolates();
$this->items->getChocolates();
}
}
class Chocolates implements Iterator {
private $items;
public function getChocolates() {
$query = ...
foreach($rows as $row) {
$this->_items[] = new Chocolate() ...
}
}
// ... necessary iterator implementation stuff
}
答案 0 :(得分:4)
bbxbby,最好的解决方案通常是最简单的解决方案。你绝对不会创建单独的迭代器对象。事实上,PHP支持并鼓励提供IteratorAggregate
接口的此类聚合。实现IteratorAggregate
的对象必须包含返回getIterator()
的{{1}}方法。这正是您的Iterator
方法所做的。关于getChocolated()
的好处是你可以将它的对象直接传递给IteratorAggregate
循环。您的代码在使用时可能看起来像这样:
foreach
然后,代码中的某个地方:
class BoxOfChocolates implements IteratorAggregate
private $chocolates = array();
public function getIterator() {
return new ArrayIterator(new ArrayObject($this->chocolates)));
}
}
答案 1 :(得分:2)
这取决于具体情况。巧克力盒是否包含多个系列?如果是这样,您需要将集合作为成员。
这样想。一盒巧克力是一个集合(即PersonList)或拥有一个集合的东西(即一辆汽车可能拥有它的最后所有者的集合)。
我认为这属于第一组
:)
答案 2 :(得分:1)
我也建议第一组,假设你的巧克力比喻对于实际的班级非常准确。
一盒巧克力真的是你的巧克力系列,因此想要迭代那个盒子里的巧克力是有意义的。添加一个单独的巧克力列表并没有真正添加任何值,只是似乎添加了一个不必要的层。
答案 3 :(得分:0)
好吧,我不懂PHP,所以我无法正确回答这个问题,但我会尝试将它与我所知道的区域联系起来。
在C#中,有两个接口:IEnumerable和IEnumerator。在您的示例中,BoxOfChocolates将是Enumerable,Chocolates将是枚举器。
Enumerables只有一个返回枚举器的方法。枚举器具有当前项的概念,以及移动到下一项的方法。在大多数情况下,Enumerator类不会被“看到”。例如,在“foreach(boxOfChoclates中的巧克力项目)”行中,boxOfChocolates是一个Enumerable;这个Enumerator对象完全被foreach隐藏。
答案 4 :(得分:0)
很简单,容器就是实现迭代器的地方。
答案 5 :(得分:0)
我认为你应该将你的集合与迭代器分开。我同意@James Curran的观点,即集合通常都有迭代器 - 事实上,它们可能有几个。例如,你可能想要一个用坚果跳过糖果的迭代器(虽然典型的情况是想要一个反转顺序的人)。在这种情况下,next()方法的含义会发生变化。要处理它,请在包含自己的迭代语义的单独类中实现迭代器。提供集合中的方法以获取正确排序的迭代器。这确实是一个关注点分离的问题。该集合并不关心用户如何迭代它,这就是迭代器的关注点。