Rolf b: Webseiten Artikel & Gästebuch einträge mit Factory Pattern?

Beitrag lesen

Hallo MB,

die Idee des Factory-Patterns ist, dass Du eine Familie von Klassen hast, die alle eine Methode CreateFooObject zur Erzeugung eines Objekts bereitstellen. Diese Methode ist entweder auf einer gemeinsamen Superklasse BaseFactory oder auf einem gemeinsam implementierten Interface IFactory definiert (alle Namen willkürlich gewählt)

Der NUTZER der Factory bekommt ein Objekt der Klasse BaseFactory bzw. IFactory, und weiß nicht, welche konkrete Implementierung er bekommen hat. Er ruft CreateFooObject auf, und bekommt ein Objekt. Welches genau, legt die Factory fest. Natürlich müssen alle Factories so gebaut sein, dass die Familie der erzeugten Foo-Objekte einen sinnvollen Satz gemeinsamer Eigenschaften haben.

Ein Beispiel: Du schreibst einen Satz Factory-Klassen, die Dir ein Objekt mit Texten liefern. Du hast 3 Factories. Eine holt die Texte aus einer Datenbank, die andere aus einer XML-Datei, die dritte hat sie fest eingebaut. Dem Objekt, in dem Du später die Texte brauchst, gibst Du bei Erzeugung eine Instanz einer dieser Factories mit. Das Objekt weiß nur, dass es eine ITextFactory als Parameter bekommt, und dass dieses Objekt eine GetTextFormatter() Methode hat. Der TextFormatter ist ein Objekt mit Methoden, die Dir die Textbausteine liefern bzw. spezfische Aufbereitungen enthalten.

D.h. eine Factory liefert Dir eine bestimmte Implementierung einer Basisklasse oder eines Interfaces. Ohne Factory-Pattern hättest Du eine EINZELNE Methode mit einem switch darin, der je nach konfiguriertem Szenario die eine oder andere Implementierung liefert. Das Factory-Pattern löst den Switch in Polymorphie auf.

Sooo. Und jetzt zu Factory und deinen Artikeln. Du müsstest erstmal überlegen, ob Du unterschiedliche Artikeltypen hast, die unterschiedliche Aufbereitung brauchen. Oder ob Du vielleicht unterschiedliche Darstellungsarten hast, für die Du jeweils eine andere Klasse bereitstellen willst, die die Aufbereitung für die Darstellung übernimmt.

Man angenommen, du hast Artikelarten A, B und C. Und Du hast - vom User auswählbare - Designs X,Y und Z. Und nehmen wir mal an, die Designs sind so unterschiedlich, dass sie nicht allein mit CSS machbar sind, sondern auch unterschiedliches HTML brauchen. Dann hast Du 9 mögliche Kombinationen, wie Du einen Artikel Nr. 4711 aufbereiten können musst.

Mit Factories kann man das so lösen: Bevor Du die Seite erzeugst, holst Du aus den User-Settings die gewünschte Darstellungsart und erzeugst eine Renderer[1]-Factory für diese Darstellungsart. Es gibt 3 Factories, und jede hat eine Methode "GetRenderer(artikeltyp)". Wenn Du einen Artikel aufbereiten willst, dann kennst Du seinen Typ. Du rufst also

    $renderer = $factory->getRenderer($typ);

auf und bekommst ein Objekt aus einer von 9 möglichen Klassen - abhängig von Artikeltyp und Darstellungsart. Dem sagst Du nur noch

   $renderer->render($article);

und der Artikel wird zu HTML. Natürlich musst Du alle 9 Klassen programmieren, natürlich ist es sinnvoll, die so zu bauen, dass in ihnen möglichst viel wiederverwendet wird. Du kannst innerhalb der Factory-Methoden unterschiedliche Techniken nutzen, um einen switch über die möglichen Arten oder Typen zu vermeiden (weil Du es vermeiden willst, die Factory anzupassen nur weil ein neuer Typ hinzukommt). Gerne genommen wird hier "Convention before Configuration", d.h. wenn Du Typen A, B und C hast, schreibst Du Klassen RenderTypA, RenderTypB und RenderTypC, und die Factory verwendet Reflektionstechniken wie diese:

   $renderClass = "RenderTyp" + $type;
   $renderer = new $renderClass(...);

Kommt nun ein Typ D hinzu, baust Du einfach eine Klasse RenderTypD und musst an der Factory nichts ändern.

So, das war nun ein grober Abriss, einiges an Hirnschmalz wirst Du selbst noch investieren müssen. Viel Glück 😉

Rolf

--
Dosen sind silbern

  1. „to render“ heißt "machen", "wiedergeben" und bezeichnet beim Programmieren den Vorgang, eine bestimmte Darstellung von Informationen zu erzeugen. ↩︎