hi,
Somit könnte man für PDFs eine Extra PDF Klasse benutzen - Faktorierung.
Jow, auch ein guter Ansatz. Es gibt halt verschiedene Wege und Entwurfsmuster. Vererbung ist auch nicht immer und überall angebracht, ich habe die Erfahrung gemacht, dass ich eine Klasse, von der ich erben möchte, sehr genau kennen sollte und das ist bei den Klassen, die ich selber schreibe der Fall. Wenn eine fremde Klasse einige Dutzend Methoden hat und von dieser Klasse letztendlich nur eine Methode gebraucht wird, ist eine Delegation sinnvoller als eine Vererbung.
Mehrere Klasseninstanzen in der main sind auch ok, es ist eine Frage der Übersichtlichkeit und eine Frage der Wiederverwertbarkeit zum Vermeiden von redundanten Code. Beispielsweise habe ich eine Klasse 'Warenkorb' für die Methoden, die für den Warenkorb zuständig sind. Die Klasse 'Bestellung' muss jedoch auch auf den Warenkorb zugreifen und somit erbt die Klasse Bestellung von Klasse Warenkorb. Der Bestellvorgang ist eine Transaktion und eine Solche über zwei verschiedene Klasseninstanzen abzuwickeln macht den Code in der main unübersichtlich, an der Stelle nämlich sitzt der Controler für die Prüfung der Benutzereingaben mit völlig anderen Zuständigkeiten.
Factory Patterns in Verbindung mit Singleton: Ich will keine Vorträge halten, steht mir nicht zu ;)
Aber mal in Kürze, wie das Erstellen einer PDF bis hin zur Auslieferung an den Webserver bei mir abläuft: Allein das Response-Objekt (RO) ist dafür zuständig, die erste zu rufende Methode sendet den Content-Type-Header, wobei sich in der factory auch unterschiedliche Content-Types ergeben können, die als Attribut im RO liegen. Wenn beispielsweise Fehler aufgetreten sind, wird da kein application/pdf gesendet, sondern text/html.
Was in der RO-Method bleibt, ist die Prüfung auf mögliche Fehlerfälle z.B. keine Daten (die Berechtigungen werden bereits weiter oben im Response-Handler geprüft), erst dann wird bei mir eine Instanz der PDF-Klasse erstellt. Das PDF wird temporär zusammengebaut und auch hier muss geprüft werden, ob dabei nichts schiefgegangen ist (Exception). Wenn alles ok, übernimmt RO den für diesen URL vorgesehenen Content-Type (application/pdf) in die Header-Method.
Die ganze Prozedur ist in einer Methode des RO in der Response-Klasse (CMS) untergebracht. Der Name der dem URL zugeordneten Methode steht in der Konfiguration, die bei jedem Request geladen wird. Um die Verwirrung komplett zu machen: Package main{} gibt es nur im Response-Handler (im Webserver konfiguriert), der erstellt das RO und das ruft anhand des Request die entsprechenden Methoden auf. Liegen Benutzereingaben vor, steht der Name der Methode ebenfalls anhand des Request fest wobei z.B. ein Login-Formular an unterschiedlichen URLs konfiguriert sein kann, jedoch stets die gleichen namentlichen Methoden über RO aufgerufen werden.
Soll zum URL ein Template geladen werden, steht das ebenfalls in der Website-Config. In diesem Fall gibt es bei mir wegen der Abwärtskompatibilität (Templates habe ich erst später eingeführt) drei Methoden: zwei Methoden wie bisher zur Ausgabe der Response, je nachdem ob Parameter anliegen oder nicht. Die dritte (bei Templates zusätzliche) Methode ist der Controller, der in der Website-Config namentlich genannt ist.
Ein Template-Prozess (expand) muss immer stattfinden, sonst sind in der Response die Platzhalter zu sehen ;)
Schönen Sonntag,
O'Horst
(O'Henry muss ich mal wieder lesen, ich freue mich auf lange Winterabende)