Tach!
public function __construct(array $links, Navi_Decorator $decorator)
Das meiste in deinem Bsp. ist selbstredend, nur der 2. Parameter. Warum steht da die Klasse Navi_Decorator drin, diese wird doch später als neues Objekt Seperat aufgerufen? Und wie nennt sich die Schreibweise für diese Parameter, also das neben der Variable "array" steht, oder der Klassenname (hier "Navi_Decorator")?
Type Hinting. Das hilft zu verhindern, dass du Objekte einer falschen Klasse übergeben kannst. Arrays sind ins Type Hinting auch aufgenommen, andere Typen gehen nicht.
Wie darf ich ein "Array von diesen Klassen" verstehen? Soll ich jeden einzelnen Link des Menus in einem Objejt speichern?
Ja.
Wäre das nicht zuviel Overhead, wenn viele Links exisitieren?
Jein. Ein Objekt mit drei Eigenschaften ist nicht wesentlich anders strukturiert als ein Array mit drei Elementen. Deine Überlegung ist auch eher theoretischer Natur. Monstermenüs wirst du kaum bauen. Aber wenn du die Betrachtung mal auf Wald-und-Wiesen-Script vs. OOP ausweitest - einen Tod musst du sterben. Die Eleganz der OOP mit ihrem Overhead oder zu Fuß und Performance. Performance ist in der Regel ausreichend vorhanden. Die Eleganz einer Lösung wird sich bei Erweiterungen positiv bemerkbar machen.
Ich habe es bei mir bislang so gelöst, dass ich das Resultat aus der Datenbank direkt als Linkliste speichere, ohne erst in ein Array zu kopieren. Das ist ja noch mit das einfachste.
Ja, aber unflexibel. Du baust dann das gesamte Konstrukt um, statt nebenher einen neuen Dekorator zu erstellen und diesen dann einfach nur zu übergeben. Und wenn das nicht gefällt, nimmst du ebenso einfach wieder den alten Dekorator. Bei der direkten Methode musst du den bisherigen Code wiederherstellen.
Außerdem bietet PHP die Möglichkeit, dass Objekte ebenfalls mit "foreach" durchlaufen werden können, indem man das Iterator- oder das IteratorAggregate-Interface implementiert. Man würde also kein Array mehr in "Navi" hineingeben, sondern ein iterierbares Objekt "Navi_Linklist", welches dann einzelne "Navi_Link"-Objekte ausspuckt.
Hier stehe ich komplett auf den Schlauch.
Ein iterierbares Objekt empfiehlt sich dann, wenn neben dem reinen Speichern, das auch ein Array erledigen kann, noch weitere Eigenschaften und Methoden benötigt werden. Hier ist es aber anders. Wenn du Datenbeschaffung und die weitere Verarbeitung trennen willst, musst du zuerst die Daten in einer geeigneten Umgebung ablegen (ein Array zum Beispiel). Der Verarbeiter kann dann mit ihnen machen was er will. Das Anlegen kostet zumindest Zeit, Platz weniger, PHP ist intelligent genug, keine Kopien im Speicher anzulegen, wenn sich die eigentlich aus deiner Sicht kopierten Daten nicht ändern. Den Aspekt des Fetchens und Array-Anlegens kannst du vereinfachen, indem du aus der Datenbeschaffung kein Array sondern nur einen Iterator an den Verarbeiter weitergibst. Der Verarbeiter iteriert diesen Iterator und dieser fetcht bei jedem Schritt einen Datensatz und übergibt ihn. Für dich sieht es aus wie foreach über ein Array, in echt ist es aber ein Lazy Fetching. Der Nachteil an der Lösung ist jedoch, wenn du beim Verarbeiten mehrfach über die Daten iterieren musst. Der Iterator ist nach einem Durchlauf abgelaufen. Ein Neustarten scheitert normalerweise daran, dass das Fetchen ein einmaliger Vorgang ist. Die MySQL(i)-API legt jedoch im Hintergrund die gesamte Ergebnisdatenmenge aus der SQL-Abfrage im Speicher ab, so dass du den Fetch-Zeiger problemlos wieder auf den Anfang stellen kannst, wenn ein erneuter Fetchvorgang stattfinden soll. Iterator ist für den einmaligen Gebrauch vorgesehen, mit IteratorAggregate kann man mehrfach durchlaufbare Iteratoren erstellen.
dedlfix.