Haha... lol. Maar die getIterator heb ik toch nodig om door de class property te loopen? Die getIterator wordt automatisch aangeroepen, zodra je gaat loopen. Daarom is mijn stelling dat het onzin is om die iterator apart aan te roepen. Snap je mijn gedachtengang?
Huh... ik snap niet wat je bedoelt. In jouw beide voorbeelden gebruik je zelf ook een foreach.
Daarnaast, in de getIterator method kan ik precies aangeven welke property wil doorlopen. Het enige wat ik onzinnig vind als je handmatig de getIterator method aan gaat spreken terwijl dat niet nodig is.
<?php
$iterator = $paths->getIterator();
foreach ($iterator as $k=>$v) {
}
// versus
foreach ($paths as $k=>$v) {
}
?>
Dat eerste voorbeeld vind ik dus onzinnig. Maar het zal wel aan mij liggen.
Ik heb nog steeds de indruk dat je de IteratorAggregate interface gebruikt terwijl de Iterator interface meer op zijn plaats is. Waar aggregeer je objecten? Dáárvoor is de IteratorAggregate interface bedoeld. Aggregeer je geen objecten, gebruik dan de Iterator interface.
Ward, ik snap nog steeds het verschil niet. Met IteratorAggregate kun je keurig aangeven WAT je wilt loopen. Welke class property. Dat zie ik zowel in mijn en jouw link terugkomen in de voorbeelden.
Als je de Iterator interface implementeert, moet je next en previous en weet ik het wat voor methods implementeren in je class. Bij de IteratorAggregate interface hoef je alleen maar aan te geven welke property je wilt kunnen loopen en verder niks. Nogmaals zie ook http://www.php.net/manual/en/class.iteratoraggregate.php
In het 1e voorbeeld kun je "return new ArrayIterator($this);" ook vervangen door bijv. "return new ArrayIterator($this->some_property);".
Ik zie niet zo goed wat ik dan fout doe, of ik begrijp niet wat je bedoelt.
Als ik de Iterator interface implementeer maak ik het mezelf toch veel lastiger omdat ik een hoop methods moet implementeren. Nu hoef ik alleen getIterator te implementeren en ik ben klaar. Wat doe ik dan verkeerd volgens jou?
Er is geen goed of fout, maar er zijn wel verschillen.
Met een foreach voer je een iteratie uit, maar niet elke iteratie is een foreach. Je mag de argumentatie dus niet omkeren. Alle honden zijn dieren, maar niet alle dieren zijn honden.
De methode getIterator() heeft een bestaansrecht wanneer je binnen het geaggregeerd object $bibliotheek voor de gehele collectie boeken een andere iteratie uitvoert dan voor de hoofdstukken van één boek. (Abstract voorbeeld: de boeken zouden alfabetisch op titel kunnen worden geïtereerd en de hoofdstukken numeriek op hoofdstuknummer, zelfs al hebben hoofdstukken ook titels.)
Je maakt nu een soort negatieve non-keuze voor een interface: je kiest de IteratorAggregate interface omdat die maar één methode heeft die je niet wilt implementeren en de Iterator interface meerdere methoden heeft die je niet wilt implementeren. Laat die interfaces dan links liggen en schrijf zelf een schone interface met methoden die je wél wilt implementeren.
Correct, maar het voornaamste pluspunt dat daar wordt genoemd, is "a more concise and more readable code". En dat is ook het argument dat je zelf aandraagt: ik kies de interface met de minste methoden, want dan hoef ik minder te implementeren. En die ene methode die je dan zou moeten implementeren, wil je er liefst ook nog uitjassen, desnoods met een *MUST NOT* in commentaar.
Ik vind dat minimalisme een non-argument, want het aantal methoden of regels code zegt niets over de geschiktheid van een interface.
Mijn punt is dat je niet iets tweederangs moet lenen als zelf iets eersterangs bouwen beter is. Zoek een interface die de data-objecten precies zo afhandelt als jij wilt. Bestaat die interface nog niet, dan schrijf je deze zelf. Maar ga niet iets lenen dat "ongeveer in de buurt komt". Dat doe je nu eigenlijk wel: je implementeert een interface met maar één methode, maar die ene methode wil je niet implementeren. Dan is de interface dus niet geschikt voor je doel.
Als het uitvoeren van een loop met een foreach echt je enige doel is, kun je ook nog overwegen om helemaal geen interface te implementeren.