hotti: Name für Entwurfsmuster

mein Perl-Framework, was von mod_perl zu mod_cgi kompatible Sourcen hat, implementiert folgendes Entwurfsmuster:

Es gibt _eine_ Instanz, die sich vom eingehenden Request bis zum Ausliefern der Response für _alles_ (Verarbeiten von Eingaben, POST, GET, PUT-Requests, Response-Header, Content) verantwortlich zeichnet.

Es gibt einen Fachausdruck für dieses Muster, ich habs mal irgendwo gelesen, leider vergessen, es zu notieren. Es ist nicht das Singleton-Pattern, aber diesem ähnlich.

Wenn jemand den Namen fürs Kind hier zur Hand hat, würde mich freuen.

Schönen Sonntag.

--
Wenn der Kommentar nicht zum Code passt, kann auch der Code falsch sein.
  1. hier:

    Wenn jemand den Namen fürs Kind hier zur Hand hat, würde mich freuen.

    isses

    Schönen Sonntag.

    Weiterhin ;)

    --
    Wenn der Kommentar nicht zum Code passt, kann auch der Code falsch sein.
    1. Hi,

      Es gibt _eine_ Instanz, die sich vom eingehenden Request bis zum Ausliefern der Response für _alles_ (Verarbeiten von Eingaben, POST, GET, PUT-Requests, Response-Header, Content) verantwortlich zeichnet.

      http://de.wikipedia.org/wiki/Single-Responsibility-Prinzip

      ehm, das SRP beschreibt das genaue Gegenteil von dem Pattern, was du implementiert hast. Sieht man schon daran, dass du das Wort "alles" verwendest und dieses "alles" eine Mächtigkeit größer 1 hat.

      Bis die Tage,
      Matti

      1. Hi,

        Es gibt _eine_ Instanz, die sich vom eingehenden Request bis zum Ausliefern der Response für _alles_ (Verarbeiten von Eingaben, POST, GET, PUT-Requests, Response-Header, Content) verantwortlich zeichnet.

        http://de.wikipedia.org/wiki/Single-Responsibility-Prinzip

        ehm, das SRP beschreibt das genaue Gegenteil von dem Pattern, was du implementiert hast. Sieht man schon daran, dass du das Wort "alles" verwendest und dieses "alles" eine Mächtigkeit größer 1 hat.

        <cite class="Link siehe oben">In der objektorientierten Programmierung sagt das SRP aus, dass jede Klasse nur eine fest definierte Aufgabe zu erfüllen hat. In einer Klasse sollten lediglich Funktionen vorhanden sein, die direkt zur Erfüllung dieser Aufgabe beitragen.</cite>

        Genauso funktioniert und ist mein Framework aufgebaut.

        1. Hakuna matata!

          <cite class="Link siehe oben">In der objektorientierten Programmierung sagt das SRP aus, dass jede Klasse nur eine fest definierte Aufgabe zu erfüllen hat. In einer Klasse sollten lediglich Funktionen vorhanden sein, die direkt zur Erfüllung dieser Aufgabe beitragen.</cite>

          Genauso funktioniert und ist mein Framework aufgebaut.

          Mag ja sein, dass du das SR-Prinzip auch umsetzt, aber das ist jedenfalls nicht die Bezeichnung für eins das Muster, welche du in deiner Fragestellung beschrieben hast und deren Namen du suchst.

          Es gibt _eine_ Instanz

          Die Instanz ist also ein Singleton.

          die sich vom eingehenden Request bis zum Ausliefern der Response für _alles_ [...] verantwortlich zeichnet.

          Das ist ein Front Controller, wie Daniel2 schon richtig erkannt hat. Der Front Controller ist ein eigenes Muster und hat nichts mit dem Controller im MVC-Muster zu tun, ich glaube dass dieses Missverständnis zu eurer Diskussion geführt hat.

          Macht dein Front Controller denn wirklich alles? Gibt es keine andere Klassen oder Funktionen in deiner Architektur?

          Auf deine Fragestellung passen diverse Muster, was keine große Überraschung ist, weil sich Designpatterns eben überschneiden. Das Singleton-Muster und das Front Controller-Muster sind ganz offensichtlich zu erkennen, jenachdem wie komplex dein Front Controller ist, könnte er auch ein Gottobjekt oder ein Big ball of mud sein. Die letzten beiden Kandidaten sind aber bekannte Anti-Pattern und stehen im Wiederspruch zum SRP.

          --
          “All right, then, I'll go to hell.” – Huck Finn
          1. Hakuna matata!

            Wiederspruch

            Der Wiederspruch ist übrigens auch ein bekanntes Anti-Pattern der deutschen Rechtschreibung.

            --
            “All right, then, I'll go to hell.” – Huck Finn
            1. Hakuna matata!

              Wiederspruch

              Der Wiederspruch ist übrigens auch ein bekanntes Anti-Pattern der deutschen Rechtschreibung.

              Die Deutsche Rechtschreibung hat ja auch mit Recht (und Gesetz) gar nichts zu tun :)

          2. Hakuna matata!

            <cite class="Link siehe oben">In der objektorientierten Programmierung sagt das SRP aus, dass jede Klasse nur eine fest definierte Aufgabe zu erfüllen hat. In einer Klasse sollten lediglich Funktionen vorhanden sein, die direkt zur Erfüllung dieser Aufgabe beitragen.</cite>

            Genauso funktioniert und ist mein Framework aufgebaut.

            Mag ja sein, dass du das SR-Prinzip auch umsetzt, aber das ist jedenfalls nicht die Bezeichnung für eins das Muster, welche du in deiner Fragestellung beschrieben hast und deren Namen du suchst.

            Es gibt _eine_ Instanz

            Die Instanz ist also ein Singleton.

            Ja, es ist ein Singleton.

            die sich vom eingehenden Request bis zum Ausliefern der Response für _alles_ [...] verantwortlich zeichnet.

            Das ist ein Front Controller, wie Daniel2 schon richtig erkannt hat. Der Front Controller ist ein eigenes Muster und hat nichts mit dem Controller im MVC-Muster zu tun, ich glaube dass dieses Missverständnis zu eurer Diskussion geführt hat.

            Och ich hab das schon verstanden und auch nochmal gezielt gesucht: In der Apache-Welt heißt das Teil ResponseHandler und ich habe nirgendwo gelesen, dass ResponseHandler == Frontcontroller gesetzt wird.

            Macht dein Front Controller denn wirklich alles? Gibt es keine andere Klassen oder Funktionen in deiner Architektur?

            Mein ResponseHandler (von mir aus FC) ist die Basisklasse für an URLs gebundene Subklassen, Beispiel:
            URLs: /foo.html, /bar.html, /feedback.html nutzen lt. Konfiguration ein Template, was aus dem Dateisystem geladen wird (der Dateiname ist konfigurierbar). Diese URLs sind über die Routingtable an class=TemplateFile gebunden.

            TemplateFile erbt vom FC u.a. den Konstruktor (in Perl gewöhnlich als new() benannte Klassenmethode) und definiert mindestens eine der Interface-Methoden, z.B. um das Template nach $singleton->{BODY} zu laden.

            URL /feedback.html bekommt ein zusätzliches Attribut verpasst: interface=Feedback weil hier Benutzereingaben zu verarbeiten sind. Damit erfolgt im FC ein require Feedback.pm und für class TemplateFile werden zusätzliche Interface-Methoden in seinem Scope definiert, nachdem die Instanz->TemplateFile bereits erstellt wurde.

            Jetzt hat der Singleton alles, was er braucht, und im FC werden die Methoden des Interface aufgerufen.

            Class TemplateFile ist eine sehr einfache Klasse. Es gibt Subklassen, die wesentlich komplexer sind und die können theroetisch beliebig viele weitere Methoden definieren und weitere Klassen mit use einbinden.

            Nach dem Durchlaufen der Interface-Methoden ist die Response fertig und auch die Header (Content-Type u.a.) stehen fest; das wird dann nur noch an den Webserver geschickt.

            Auf deine Fragestellung passen diverse Muster, was keine große Überraschung ist, weil sich Designpatterns eben überschneiden. Das Singleton-Muster und das Front Controller-Muster sind ganz offensichtlich zu erkennen, jenachdem wie komplex dein Front Controller ist, könnte er auch ein Gottobjekt oder ein Big ball of mud sein. Die letzten beiden Kandidaten sind aber bekannte Anti-Pattern und stehen im Wiederspruch zum SRP.

            Mein FC (ResponseHandler) ist alles Andere als komplex. Er ist nur ein Dispatcher (Router) der den Code vermittelt und ein paar Interface-Methoden aufruft. Ca. 250 Zeilen Perl und eine flache Klassenhierarchie ;)

            MfG

            --
            Wenn der Kommentar nicht zum Code passt, kann auch der Code falsch sein.
          3. Hakuna matata!
            Auf deine Fragestellung passen diverse Muster, was keine große Überraschung ist, weil sich Designpatterns eben überschneiden.

            Und sie sind umstritten, wie z.B. das Factory-Pattern. Als Erzeugungsmuster würde mir

              
               $ro->configini('Config::Tiny');  
            
            

            eine Instanz der Klasse 'Config::Tiny' liefern. Da habe ich erstens nicht viel gekonnt und zweitens muss meine Klasse wissen, dass die einzubindende Klasse 'Config::Tiny' heißt.

            Demgegenüber ungemein praktischer wäre sowas:

              
               my $config = $ro->configini('/path/inifile');  
            
            

            weils mir gleich das Ergebnis liefert und meine Klasse gar nicht wissen muss, dass dazu eine andere Klasse 'Config::Tiny' benötigt wird, die genausogut auch 'Config::IniFiles' heißen könnte.

            Ergo: Mit meiner Auslegung Factory-Pattern bin ich flexibler und praxisnah, der Code wird austausch- und wiederverwendungsfähig.

            Schöne Grüße.

            --
            Unserer Sprachkultur (in Wort und Schrift) ist das traurige Erbe der 68er-Generation.
            1. Hakuna matata!

              z.B. das Factory-Pattern. Als Erzeugungsmuster würde mir

              $ro->configini('Config::Tiny');

              
              >   
              > eine Instanz der Klasse 'Config::Tiny' liefern. Da habe ich erstens nicht viel gekonnt und zweitens muss meine Klasse wissen, dass die einzubindende Klasse 'Config::Tiny' heißt.  
                
              Dann ist es keine Factory. Beim Factory-Pattern geht es nämlich nur darum, die konkrete Klasse nicht kennen zu müssen.  
                
              
              > Demgegenüber ungemein praktischer wäre sowas:  
              >   
              > ~~~perl
                
              
              >    my $config = $ro->configini('/path/inifile');  
              > 
              
              

              weils mir gleich das Ergebnis liefert und meine Klasse gar nicht wissen muss

              Genau, das ist halt eine Factory.

              Ergo: Mit meiner Auslegung Factory-Pattern bin ich flexibler und praxisnah, der Code wird austausch- und wiederverwendungsfähig.

              Deine Auslegung scheint mir die ganz gewöhnliche Auslegung zu sein.

              --
              “All right, then, I'll go to hell.” – Huck Finn
              1. Hakuna matata!

                weils mir gleich das Ergebnis liefert und meine Klasse gar nicht wissen muss

                Genau, das ist halt eine Factory.

                Ergo: Mit meiner Auslegung Factory-Pattern bin ich flexibler und praxisnah, der Code wird austausch- und wiederverwendungsfähig.

                Deine Auslegung scheint mir die ganz gewöhnliche Auslegung zu sein.

                Eine sehr praktische Angelegenheit ;)

                  
                    $self->render(\$self->{BODY}, $self->{STASH});  
                
                

                Lazy-Creation: Die Instanz der Template-Engine (z.B. HTML::Template) wird erst erstellt, wenn die render()-Methode aufgerufen wird. Die Template-Engine ist austauschbar und welche das ist, muss nur derjenige wissen, der die Templates bearbeitet.

                Schöne Grüße.

  2. Das Pattern, das du suchst, nennt sich Front-Controller

    1. Das Pattern, das du suchst, nennt sich Front-Controller

      Nein, mit Sicherheit nicht, weil: Isch abe gar keinen Front-Controller ;)

      Brief: Ein Request läuft in den ResponseHandler, der schaut in die Routingtable und guckt, welche Klasse an den URL gebunden ist (Default-Class=NotFound). Von dieser Klasse wird eine Instanz erstellt, welche ein Interface implementiert. Sofern die Interface-Methoden in der Klasse definiert sind, werden sie ausgeführt. Für Request-Parameter (GET, POST) ist eine der IF-Methoden zuständig, sub control{}. D.h.: Eine Parameter-Kontrolle erfolgt nicht "An der Front" sondern erst in einer der IF-Methoden (sofern vorhanden) und darüber hinaus gibt es die Möglichkeit, per Konfiguration sämtliche IF-Methoden in einer externen Package definieren zu können, also später nachdem es bereits eine Instanz der Klasse gibt.

      Darüber hinaus können auch Requests weiterer Request-Methods gehandled werden wie PUT und DELETE.

      Ausführlich auf meiner Site beschrieben ;)

      Schön' Abend.

      --
      Wenn der Kommentar nicht zum Code passt, kann auch der Code falsch sein.
      1. Das Pattern, das du suchst, nennt sich Front-Controller

        Nein, mit Sicherheit nicht, weil: Isch abe gar keinen Front-Controller ;)

        Oh, ich denke schon.

        Brief: Ein Request läuft in den ResponseHandler

        Wie auch immer du ihn nennst. Im Front-Controller-Pattern gibt es eine Klasse, die genau das macht. Request entgegennehmen, Routen + Verarbeitung an einen Controller delegieren, Response zurückgeben.

        der schaut in die Routingtable und guckt, welche Klasse an den URL gebunden ist

        Das kann ein Front-Controller entweder selbst machen, oder aber er verwendet spezialisierte Router-Klassen für diesen Zweck. Ich sehe da keine Abweichung vom Front-Controller-Pattern.

        (Default-Class=NotFound).

        Soweit auch nichts besonderes.

        Von dieser Klasse wird eine Instanz erstellt, welche ein Interface implementiert.

        Und solche Klassen nennt man dann meist Controller.

        Eine Parameter-Kontrolle erfolgt nicht "An der Front" sondern erst in [...]

        Muss auch nicht. Im ZendFramework, welches das FrontController-Pattern ebenfalls implementiert, ist es Aufgabe der Controller und/oder des Routers, die Parameter zu prüfen.

        1. Das Pattern, das du suchst, nennt sich Front-Controller

          Nein, mit Sicherheit nicht, weil: Isch abe gar keinen Front-Controller ;)

          Oh, ich denke schon.

          Naja, im ResponseHandler treffe ich eine "Vorauswahl": Gibt es Parameter (POST, GET) oder gibt es keine. Diese Kontrolle erfolgt beim Aufruf der Interface-Methoden:

            
              # Aufruf der Interface Methoden (gekürzt)  
              # $ro ist das Response-Objekt nach dem Single-Responsibility-Prinzip SRP  
              if($ro->param){  
                  $ro->execute('control');  
              }  
              else{  
                  $ro->execute('browse');  
              }  
          
          

          Brief: Ein Request läuft in den ResponseHandler

          Wie auch immer du ihn nennst.

          In einer mod_perl Umgebung hieß der schon immer so: PerlResponseHandler. Dieser Begriff ist keine Erfindung von mir ;)

          Und solche Klassen nennt man dann meist Controller.

          Dann wäre: PerlResponseHandler == Front-Controller ?

          Ich wüsste nicht, dass ich das schoneinmal irgendwo so gelesen habe, aber ich kann ja mal gezielt gucken ;)

          Bis dann.

          1. Naja, im ResponseHandler treffe ich eine "Vorauswahl": Gibt es Parameter (POST, GET) oder gibt es keine.

            Ein Front-Controller macht das auch so. Er schaut, welche Parameter angegeben wurden, und ruft dann den jeweiligen Controller auf.

            z.B. in einem Zend-Projekt:

            URL: http://example.org/calculation/calculate

            Daraus macht der (Default-)Router dann:

              
            $controllerName = "CalculationController";  
            $actionName     = "calculateAction";  
            
            

            Anschließend ruft er die Action (verkürzt) so auf:

              
            $controller = new $controllerName($requestObject, $responseObject);  
            $controller->$actionName();  
            
            

            Diese Kontrolle erfolgt beim Aufruf der Interface-Methoden:

            Im Zend Framework passiert diese entweder im Router (sofern man sich einen eigenen schreibt), oder eben im aufgerufenen Controller.

            Und solche Klassen nennt man dann meist Controller.

            Dann wäre: PerlResponseHandler == Front-Controller ?

            Ja. Das, was diese Klasse tut, entspricht der Definition eines Front-Controllers.

            Ich wüsste nicht, dass ich das schoneinmal irgendwo so gelesen habe, aber ich kann ja mal gezielt gucken ;)

            Stichwort: MVC

            1. Moin,

              Dann wäre: PerlResponseHandler == Front-Controller ?

              Ja. Das, was diese Klasse tut, entspricht der Definition eines Front-Controllers.

              Ich wüsste nicht, dass ich das schoneinmal irgendwo so gelesen habe, aber ich kann ja mal gezielt gucken ;)

              Stichwort: MVC

              Auch in diesem Zusammenhang habe ich noch nirgendwo gelesen, dass in der Perl-Welt ein PerlResponseHandler als Front-Controller bezeichnet wird.

              Der Begriff PerlResponseHandler ist für Apache/mod_perl geläufig, die einzige Freiheit, die ich mir rausnehme ist, dass ich für mod_cgi meine Package main ebenfalls so nenne ;)

              So denke ich, dass der Begriff "Single-Responsibility-Prinzip SRP" am ehesten passt, wobei meine Entwicklungen auch weitere Entwurfsmuster abbilden und ich bei nachträglichen Recherchen oftmals feststellen muss, dass schon manche Begriffe nicht klar definiert sind.

              Danke für Dein Interesse!

              1. So denke ich, dass der Begriff "Single-Responsibility-Prinzip SRP" am ehesten passt

                SRP ist etwas, das möglichst jede Klasse erfüllen sollte. Es handelt sich dabei weniger um ein Entwurfsmuster, sondern vielmehr um eine Richtlinie für guten Quellcode.

    2. hi Daniel2,

      Das Pattern, das du suchst, nennt sich Front-Controller

      http://www.martinfowler.com/eaaCatalog/frontController.html

      mfg

      tami

        1. hi tami,

          hi Daniel2,

          Das Pattern, das du suchst, nennt sich Front-Controller

          http://www.martinfowler.com/eaaCatalog/frontController.html

          aus http://framework.zend.com/manual/1.12/de/zend.controller.front.html

          Praktisch eine Neuerfindung des Apache-ResponseHandlers ;)

          1. Hakuna matata!

            aus http://framework.zend.com/manual/1.12/de/zend.controller.front.html

            Praktisch eine Neuerfindung des Apache-ResponseHandlers ;)

            Nein, das ResponseHandler-Interface definiert eine _clientseitige_ Schnittstelle, um auf _eingehende_ Antworten eines HTTP-Servers zu reagieren. Deshalb ist sie auch in dem Paket org.apache.http.client definiert.

            Das lässt sich eher mit JavaScripts AJAX vergleichen:

            var request = new XMLHttpRequest();  
            request.open('get', '//example.com');  
            request.send();  
            request.addEventListener('response', function ( event ) {  
               var response = event.target.response;  
            });
            

            In JavaScript wird von XMLHttpRequest automatisch eine response-Eigenschaft erstellt, wenn die Serverantwort eintrifft. Diese response-Eigenschaft kann verschiedene Typen haben, abhängig vom ContentType der Antwort. "text/plain" führt dazu, dass die response-Eigenschaft den Typ "String" bekommt. "text/html" führt dazu, dass die Eigenschaft ein DOMDocument wird. "application/json" führt dazu, dass response ein planes JavaScript-Objekt wird.

            In Java ist es ebenfalls möglich, dass Response-Objekte verschiedene Typen haben, aber weil Java statisch typisiert ist, geht das nicht so ohne weiteres wie in JavaScript. Der Typ muss irgendwo festgelegt werden, und dafür gibt es das generische Interface ResponseHandler. Das wird besser verständlich, wenn man sich die Signatur anschaut:

            ResponseHandler<T>

            „T“ ist hier ein Platzhalter für einen generischen Typen, man wird im späteren Programm vermutlich mehrere konkrete Typen haben, zum Beispiel ResponseHandler<DOMDocument> oder ResponseHandler<String>.

            Das ResponseHandler-Interface ist nur eine sehr abstrake Bauvorschrift für mögliche Implementationen. Vor allem aber definiert es eine _clientseitige_ Schnittstelle.

            Der Front Controller hingegen ist etwas, was man auf dem Server antrifft und man versteht ihn am besten einfach als Eintrittspunkt für die Webanwendung, die dann _serverseitig_ ausgeführt wird.

            --
            “All right, then, I'll go to hell.” – Huck Finn
            1. Hakuna matata!

              aus http://framework.zend.com/manual/1.12/de/zend.controller.front.html

              Praktisch eine Neuerfindung des Apache-ResponseHandlers ;)

              Nein, das ResponseHandler-Interface definiert eine _clientseitige_ Schnittstelle, um auf _eingehende_ Antworten eines HTTP-Servers zu reagieren. Deshalb ist sie auch in dem Paket org.apache.http.client definiert.

              CGI-Standard: Das G steht für Gateway, die Strecke zwischen Webserver und einem weiteren serverseitigem Prozess (Perl, PHP, ...). Letzterer ist ein freilich Client, der mit dem Webserver kommuniziert, war schon immer so, nüschd Neues ;)

              Der Front Controller hingegen ist etwas, was man auf dem Server antrifft und man versteht ihn am besten einfach als Eintrittspunkt für die Webanwendung, die dann _serverseitig_ ausgeführt wird.

              CGI-Standard: Der Front-Controller (Perl, PHP, ...) kommuniziert mit dem Webserver. Der Webserver liefert z.B. einen HTTP Status 504 Gateway Timeout, wenn er von dem ihm zugeteiltem weiteren Serverprozess (Perl, PHP, ...) in einer im Webserver/CGI-Schnittstelle konfigurierten Zeit keine Antwort bekommt, die lt. CGI-Standard ein Webserver in STDIN (1) erwartet.

              Apache-ResponseHandler definiert die IO-Kapselung (2) und ist ansonsten nur ein anderer Name für die CGI-Schnittstelle.

              1. mod_cgi: Der Frontcontroller schickt Header und Message-Body nach STDOUT (print, printf, echo, ...)
              2. mod_perl: PerlResponseHandler, FC bedient sich einer Apache2::RequestIO-Instanz zum Senden von Header und Message-Body ($r->content_type, $r->header_out, $r->print, ...)

              Schöne Grüße.

              1. Hakuna matata!

                Nein, das ResponseHandler-Interface definiert eine _clientseitige_ Schnittstelle, um auf _eingehende_ Antworten eines HTTP-Servers zu reagieren. Deshalb ist sie auch in dem Paket org.apache.http.client definiert.

                CGI-Standard: Das G steht für Gateway, die Strecke zwischen Webserver und einem weiteren serverseitigem Prozess (Perl, PHP, ...). Letzterer ist ein freilich Client, der mit dem Webserver kommuniziert, war schon immer so, nüschd Neues ;)

                Das hast du immernoch nicht richtig verstanden. Du denkst auch viel kompliziert, hier geht es ganz banal um das HTTP Client-Server-Modell. Der Apache Webserver, nginx und diverse Node.js-Programme sind HTTP-Server. Der Internet-Explorer, Firefox, Chrome und die Android Twitter App sind HTTP Clients. Das RequestHandler-Interface ist für die zweite Gruppe interessant, für HTTP Clients. Das wird auf der Projektseite der Apache HttpComponents sehr deutlich, in diesem Projekt wird auch definiert, was ein ResponseHandler ist. Mit dem Apache WebServer und CGI hat das nicht im entferntesten zu tun.

                Der Front Controller hingegen ist etwas, was man auf dem Server antrifft und man versteht ihn am besten einfach als Eintrittspunkt für die Webanwendung, die dann _serverseitig_ ausgeführt wird.

                Apache-ResponseHandler definiert die IO-Kapselung (2) und ist ansonsten nur ein anderer Name für die CGI-Schnittstelle.

                Nein, das ist wieder falsch. Löse dich mal von CGI und serverseitigen Prozessen. Der ResponseHandler definiert eine Schnittstelle um den Antworttext eines HTTP-Servers zu parsen und eine Datenstruktur daraus zu machen, mit der man einfacher arbeiten kann als mit Text.

                liebe Grüße
                1UnitedPower
                das L steht für Gefahr

                --
                “All right, then, I'll go to hell.” – Huck Finn
                1. Hakuna matata!
                  Das hast du immernoch nicht richtig verstanden. Du denkst auch viel kompliziert,

                  Ganz im Gegenteil, ich denke abstrakt.

                  Apache-ResponseHandler definiert die IO-Kapselung (2) und ist ansonsten nur ein anderer Name für die CGI-Schnittstelle.

                  Nein, das ist wieder falsch. Löse dich mal von CGI und serverseitigen Prozessen. Der ResponseHandler definiert eine Schnittstelle um den Antworttext eines HTTP-Servers zu parsen und eine Datenstruktur daraus zu machen, mit der man einfacher arbeiten kann als mit Text.

                  Es ist nicht ganz falsch, höchstens zu abstrakt formuliert meinerseits.

                  Fürs gegenseitige Verständnis:

                  CGI-Standard, mod_cgi

                  Im Webserver konfiguriert, z.B. über einen ScriptAlias, wird bei einem Request dieses Script aufgerufen und erzeugt einen serverseitigen Prozess. Ausgeführt wird die Package main.

                  PerlResponseHandler mod_perl

                  Ein im Webserver konfigurierter PerlResponseHandler definiert eine Methode mit dem Namen handler(). Bei einem Request wird diese Methode aufgerufen.

                  ====Beide Betriebsmodi nutzen den CGI-Standard 1.1====

                  Freilich wird bei mod_perl der Request und die gesamte Kommunikation Serverprozess <=> Webserver gekapselt. Was haben wir denn im Request: URL, Request_Method, Parameter, HTTP/Version. Und genau hier haben wir zwei Möglichkeiten, entweder die ResponseHandler-API zu nutzen oder mit

                  PerlOptions +GlobalRequest

                  z.B. per CGI.pm auf STDIN und Request-Parameter zugreifen zu können. Und mit

                  PerlOptions +SetupEnv

                  schließlich haben wir auch den kompletten %ENV, wo u.a. drinsteht, dass die eigentliche Schnittselle CGI/1.1 ist. Anstelle selbst in den Hash %ENV zu greifen können wir auch Methoden der ResponseHandler-API nutzen.

                  Im Grunde kann sich die Verwendung der ResponseHandler-API beschränken auf das, was über die Kapselung erfolgen MUSS, weils nicht anders geht: IO nach STDOUT. Es steht dem Entwickler frei, das zu nutzen was er für zweckmäßiger hält.

                  Dir stehts natürlich auch frei, rauszufinden, wie ein ResponseHandler für mod_php eingerichtet wird. Vermutlich so, dass der Entwickler sich nicht so ums Detail kümmern muss wie einer aus der Perl-Fraktion. Funktional auf jeden Fall so wie oben beschrieben ;)

                  1. PS:

                    PerlOptions +GlobalRequest

                    Alternative:

                      
                      CGI->new( Apache::Request-Objekt );  
                    
                    

                    Gib mal bitte mit PHP die ServerUmgebung aus und guck mal, was bei

                    'GATEWAY_INTERFACE' => 'CGI/1.1', # mod_perl

                    steht.

                    Schöne Grüße.

                  2. Hakuna matata!

                    PerlResponseHandler

                    Jetzt merk ich, dass wir die ganze Zeit aneinander vorbei reden. Tu dir einen Gefallen und google mal "Apache ResponseHandler" oder einfach nur "ResponseHandler" und dann zähl die Seiten, bis der erste Eintrag über den "PerlResponseHandler" erscheint. Der unscheinbare Prefix "Perl" macht hier einen gewaltigen Unterschied, den sollte man nicht einfach so verschlucken. Aber das kann ich dir wirklich nicht verübeln. Da hätten die mod_perl-Entwickler sich mal Gedanken darüber machen sollen, dass man vorbelastetes Vokabular nicht einfach für ganz andere Dinge wiederverwendet.

                    Btw: hier hast du es noch richtig gemacht. Das hätte ich auch als Hinweis nehmen können.

                    --
                    “All right, then, I'll go to hell.” – Huck Finn
                    1. Hakuna matata!

                      PerlResponseHandler

                      Jetzt merk ich, dass wir die ganze Zeit aneinander vorbei reden. Tu dir einen Gefallen und google mal "Apache ResponseHandler" oder einfach nur "ResponseHandler" und dann zähl die Seiten, bis der erste Eintrag über den "PerlResponseHandler" erscheint. Der unscheinbare Prefix "Perl" macht hier einen gewaltigen Unterschied, den sollte man nicht einfach so verschlucken.

                      Wieso verschlucken? Ich arbeite damit! Also mit ca. 450 Dateien womit ein Apache-ResponseHandler für mod_perl in Perl implementiert ist. Für eine Windows-Testumgebung ist das z.B. alles hier zu finden.

                      Und ich gehe mal davon aus, dass diese Implementierung schon das umsetzt, was sich Apache-Entwickler so ausgedacht haben, weil zumindest das praktische Ergebnis meinen Erwartungen entspricht und sich für meine Begriffe mit der Theorie deckt.

                      Insgesamt, denke ich, das ich das Kapitel 'Design-Patterns' ein für allemal begraben werde. Das ist was für 'Gstuierte die gerne dicke Bücher schreiben oder lesen. Auf so manche Finesse kommen erfahrene Programmierer ganz von selbst und Andere können von mir aus ihre Doktorarbeiten darüber schreiben.

                      Wie schon immer: Marx ist die Theorie, Murx ist die Praxis ;)

                      1. Hakuna matata!

                        PerlResponseHandler

                        Jetzt merk ich, dass wir die ganze Zeit aneinander vorbei reden. Tu dir einen Gefallen und google mal "Apache ResponseHandler" oder einfach nur "ResponseHandler" und dann zähl die Seiten, bis der erste Eintrag über den "PerlResponseHandler" erscheint. Der unscheinbare Prefix "Perl" macht hier einen gewaltigen Unterschied, den sollte man nicht einfach so verschlucken.

                        Wieso verschlucken?

                        Weil der PerlResponseHandler aus mod_perl nichts mit dem Apache (Java Interface) ResponseHandler zu tun hat. Die mod_perl Entwickler haben bei der Benennung ihres "PerlResponseHandlers" einfach Qutasch gemacht gemacht. Das sind zwei ähnlich klingende Namen für zwei völlig verschiedene Dinge, du sagst du ganze Zeit "Apache ResponseHandler" meinst aber eigentlich den "PerlResponseHandler".

                        --
                        “All right, then, I'll go to hell.” – Huck Finn
                        1. Hakuna matata!

                          Weil der PerlResponseHandler aus mod_perl nichts mit dem Apache (Java Interface) ResponseHandler zu tun hat. Die mod_perl Entwickler haben bei der Benennung ihres "PerlResponseHandlers" einfach Qutasch gemacht gemacht. Das sind zwei ähnlich klingende Namen für zwei völlig verschiedene Dinge, du sagst du ganze Zeit "Apache ResponseHandler" meinst aber eigentlich den "PerlResponseHandler".

                          Eventuell freunden wir uns mit dem Begriff ROLE an, im Fall Perl/FastCGI hat die 'main' die Rolle eines RESPONDERS. Der Begriff ROLE => RESPONDER in diesem Zusammenhang war mir auch neu, weil ich mit mod_fastcgi schon ewig nichts mehr gemacht habe, in den nächsten Tagen jedoch mein FW neben mod_cgi, mod_perl auch für mod_fastcgi kompatibel mache.

                          Diese drei Modi gibt es grundsätzlich auch für PHP, serverseitig kommuniziert PHP mit dem Webserver genauso wie Perl über STDIN und STDOUT (CGI/1.1).

                          MfG

          2. hi hotti,

            hi tami,

            hi Daniel2,

            Das Pattern, das du suchst, nennt sich Front-Controller

            http://www.martinfowler.com/eaaCatalog/frontController.html

            aus http://framework.zend.com/manual/1.12/de/zend.controller.front.html

            Praktisch eine Neuerfindung des Apache-ResponseHandlers ;)

            "The Front Controller consolidates all request handling by channeling requests through a single handler object. This object can carry out common behavior, which can be modified at runtime with decorators. The handler then dispatches to command objects for behavior particular to a request."

            © 2003

            "Patterns of Enterprise Application Architecture"

            Ich weiß nicht, wann der Apache-ResponseHandler "erfunden" worden ist. Ich finde ihn nicht. Ich finde lediglich: http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/client/ResponseHandler.html

            Das Ding händlet die Reponse, also die Antwort. Der FrontController ist _die_ (einzige) Eingangspforte für Requests. Er leitet Requests weiter, und kein Request kann ihn umgehen, weil (zumindest beim ZF) per redirect alle Requests an den FrontController (z.b. die index.php) dirigiert werden. Was dann mit den Responses ist, steht auf einem anderen Blatt. Ist wie bei der Rezeption bei einem Hotel oder so. Du musst dahin, was Du für eine Antwort kriegst und von wem, kannst Du daraus nicht schließen ...;

            mfg

            tami

            1. Hakuna matata!

              Ich weiß nicht, wann der Apache-ResponseHandler "erfunden" worden ist. Ich finde ihn nicht. Ich finde lediglich: http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/client/ResponseHandler.html

              Den meint hotti nicht, er meint den PerlResponseHandler.

              --
              “All right, then, I'll go to hell.” – Huck Finn
              1. hi 1UnitedPower,

                Hakuna matata!

                Ich weiß nicht, wann der Apache-ResponseHandler "erfunden" worden ist. Ich finde ihn nicht. Ich finde lediglich: http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/client/ResponseHandler.html

                Den meint hotti nicht, er meint den PerlResponseHandler.

                Ja, das hatte ich schon mitbekommen. Ich lese:

                "The handler (response) phase is used for generating the response."

                Und im ZF:

                "Das Response-Objekt ist das logische Gegenstück zum Request-Objekt. Sein Zweck ist es, Inhalte und/oder Header zu vereinigen, um sie in einem Rutsch zu versenden. Zusätzlich übergibt der FrontController alle aufgefangenen Ausnahmen an das Response-Objekt, um dem Entwickler das Verarbeiten von Ausnahmen zu ermöglichen."

                http://framework.zend.com/manual/1.12/de/zend.controller.response.html

                Es wird also eine Unterscheidung getroffen zwischen Eingang (Front) und Ausgabe (Response).

                tami

                1. Hakuna matata!

                  Ja, das hatte ich schon mitbekommen. Ich lese:

                  "The handler (response) phase is used for generating the response."

                  Und im ZF:

                  "Das Response-Objekt ist das logische Gegenstück zum Request-Objekt.

                  Die Response-Klasse Zend\Http\Response wird _serverseitig_ gebraucht, um eine Antwort zu erzeugen und an den _Client_ zu schicken.

                  Der Apache ResponseHandler  wird clientseitig gebraucht, um eine Antwort vom _Server_ entgegen zu nehmen und zu parsen.

                  Du vergleichst hier also Äpfel mit Birnen.

                  Der PerlResponseHandler wird _serverseitig_ gebraucht, um _HTTP-Anfragen_ an die Laufzeitumgebung von PERL wieterzuleiten. Er ist intuitiv betrachtet ein _RequestHandler_ und kein ResponseHandler, weil damit eben eintreffende Requests behandlet werden und keine eintreffenden Responses, wie im Falle des Apache ResponseHandlers.

                  Ich würde den PerlResponseHandler aber nicht als Front Controller bezeichnen, weil der Front Controller imho. auf der Anwedungsebene zu finden ist, diese Art von Dispatching findet aber statt, bevor die Kontrolle an die Anwendung weitergeleitet wird. hottis Interpretation lasse ich aber auch gelten.

                  Es wird also eine Unterscheidung getroffen zwischen Eingang (Front) und Ausgabe (Response).

                  Serverseitig ist der Request der Eingang und der Response der Ausgang.
                  Clientseitig ist der Request der Ausgang und der Response der Eingang.

                  In Frameworks, wo sich die Entwickler etwas mehr Gedanken über die Benennung ihrer Klassen machen, trifft man deshalb oft auf die Vertreter:

                  HttpClientRequest
                  HttpClientResponse
                  HttpServerRequest
                  HttpServerResponse

                  --
                  “All right, then, I'll go to hell.” – Huck Finn
                  1. hi 1UnitedPower,

                    HttpClientRequest
                    HttpClientResponse
                    HttpServerRequest
                    HttpServerResponse

                    Nun, das ZF ist ja nur auf dem Server zu finden, oder? ;-) Ansonsten natürlich full ack oder wie das heißt.

                    mfg

                    tami

                    1. Hakuna matata!

                      HttpClientRequest
                      HttpClientResponse
                      HttpServerRequest
                      HttpServerResponse

                      Nun, das ZF ist ja nur auf dem Server zu finden, oder? ;-)

                      Richtig, trotzdem kann eine Zend-Anwendung auch mal Http-Client spielen.

                      --
                      “All right, then, I'll go to hell.” – Huck Finn
            2. hi hotti,

              also gut, mal ein bischen ausführlicher ;)
              Mein PerlResponseHandler, nennen wir ihn FWNG, ist eine Package, deren Perl-Sourcen beim Apache-Start vom Perl-Interpreter kompiliert werden. In dieser Phase (Apache-Start) ist das so, das ist mod_perl.

              Ein PerlResponseHandler ist, aus der Sicht des Apachen via CGI/1.1 ein Client, der mit dem Apachen via IO (STDIN, STDOUT) kommunizieren kann (er ist kein HTTP-Client, kann sein, dass ich hier Käse verzählt habe, sorry).

              Ein PerlResponseHandler definiert eine Methode mit dem Namen handler(). Bei einem HTTP-Request wird diese Methode aufgerufen und damit steht in dieser Methode eine Instanz der Klasse Apache::Request zur Verfügung.

              FWNG nutzt Methoden der Instanz Apache::Request um alles zu ermitteln, was der Request mitbringt, URL, Request-Header, Parameter usw. Beim ersten, nach dem Apache-Start erfolgenden Request, wird die RoutingTable und die Realm-Configuration in den MEMCache geladen. Ansonsten dann wird in den MEMCache (RoutingTable) geschaut, welche class an den URL gebunden ist.

              Realm: Je nach Benutzergruppe, Default-Realm: public

              Die Klasse wird kompiliert (das passiert auch nur beim ersten Request) und danach wird eine Instanz dieser Klasse erzeugt. Dabei erbt diese Subklasse von FWNG ein paar interessante Methoden und kriegt alles, was zum Request gehört, fein säuberlich in Attribute verpackt. Diese Instanz nenne ich Response-Objekt, das ist z.B. eine Instanz der Klasse MVC::Feedback weil das Feedback-Formular aufgerufen wurde (RoutingTable, realm public: /feedback.html => class=MVC::Feedback).

              Über das Response-Objekt RO werden nun alle Methoden des FWNG-Interfaces aufgerufen. Verzweigungen können sich ergeben, wenn Benutzereingaben vorhanden sind. Die komplette Business-Logik liegt in class=MVC::Feedback, bzw. in den Methoden des Framework-Interfaces, welche class MVC::Feedback definiert. Welches Template geladen wird, weiß entweder die Subklasse MVC::Feedback oder sie bekommt über ein in der URL-Konfiguration konfiguriertes Attribut mitgeteilt, wo das Template zu holen ist, auf jeden Fall ist das vom Code sauber getrennt.

              I.d.R. haben die Methoden des FWNG-Interface nur wenige Zeilen, ggf. werden Sourcen ausglagert (Factory). Beispiel in MVC::Feedback:

                
              # Benutzereingabe, control wird aufgerufen  
              # eine Methode des FW-Interface  
              sub control{  
                  my $self = shift;  
                  # Mit den Eingaben alle Felder wieder ausfüllen  
                  # die Eingabefelder sind email und mesg  
                  $self->{STASH}{email} = $self->trim(($self->param('email')))  
                     || return $self->error("Bitte geben Sie Ihre eMail-Adresse ein");  
                  $self->{STASH}{mesg}  = $self->trim(($self->param('mesg')))  
                     || return $self->error("Bitte geben Sie Ihre Nachricht ein");  
                
                
                  # Schlüsselparameter Senden-Butten.Name  
                  if($self->param('send')){  
                      $self->eav('title','Nachricht gesendet');  
                      $self->sendmail() or die $@; # Mögliche Exception: MTAd läuft nicht  
                                                   # alle Exceptions werden sauber im Browser ausgegeben  
                      # Ergebnis ausgeben  
                      $self->{STASH}{form} = undef;  # Template wird umgeschaltet  
                      $self->{STASH}{mesg}  =~ s/\n/<br>/g;  
                  }  
                  else{  
                      $self->error('Unbekannter Parameter');  
                  }  
              }  
              
              

              Zurück in sub handler() hat das Response-Objekt nun alles, was die Ausgabe braucht. Platzhalter in RO->STASH. Wir rufen auf:

                
                $r->print($ro->start_html, $ro->menu, $ro->body, $ro->end_html);  
                # $r ist die Apache::Request Instanz und kommuniziert mit dem Webserver über STDOUT  
              
              

              Das alles läuft in einem Try-Block. Andere URLs => andere Subklassen. Mehrere URLs können diegleiche Klasse verwenden, Unerschiede sind dann über Attribute geregelt. FWNG ist eine abstrakte Klasse, verwendet wird nur die Erweiterung (Subklasse).

              Ebenfalls über ein Attribut konfigurierbar, ist es möglich, alle FW-IF-Methoden in einer extra Package (Trait) zu definieren. Wir können das auch Decorator nennen, weil das NACH der Instanzerstellung möglich ist.

              Flache Klassenhierarchie, saubere Verzeichnisstruktur, aufgeräumter Code. Leider sieht die Praxis da draußen komplett anders aus, da herrscht das Onion Pattern vor.

              Schöne Grüße ;)

              1. PS:

                Flache Klassenhierarchie, saubere Verzeichnisstruktur, aufgeräumter Code. Leider sieht die Praxis da draußen komplett anders aus, da herrscht das Onion Pattern vor.

                In diversen Firmen habe ich sehr gute Ansätze (mod_perl, mod_cgi) gesehen, die jedoch leider auch das Zwiebel-Wachstum begünstigen. Letztendlich fließen gerade solche Erfahrungen in meine eigenen Entwicklungen ein und da Zwiebeln nicht auf kargem Boden wachsen, habe ich die Entwicklung meines Frameworks gezielt in diese Richtung gelenkt und viele Sachen abgespeckt ohne dass Funktionalität verlorengeht (ganz im Gegenteil), insbesondere in Sachen Klassenentwurf, Code-Redundanzen, Datenhaltung und Datenstrukturen.

                Es ist manchmal erschreckend, was nach monatelanger Entwicklungsarbeit an Code übrigbleibt, aber wenn ich sehe, was Andere für Monster bauen, die letztendlich auch nur Dasselbe machen, dann weiß ich, dass sich die Arbeit gelohnt hat.

                Schluss für heute ;)

              2. hi hotti,

                im Grunde ist es aber ziemlich Latte, was hinter dem Frontcontroller funktioniert, und ob der aus Apache-Sicht ein Client ist oder nicht. Das Pattern bezieht sich darauf, dass alle Requests über den Front-Controller gehen, ausnahmslos. Und im FrontController wird entschieden, wie zu verfahren ist. Die Zuordnung von Request /abc/def scheint mir bei Dir ähnlich wie im schon erläuterten ZF. Der Request-Path wird einer Funktion einer Klasse zugeordnet. Das ist aber (im ZF zumindest) schon eine Form von (Standard-)Routing.

                mfg

                tami

                1. hi tami,

                  im Grunde ist es aber ziemlich Latte,

                  Was heißt hier Latte? Ungezählte Autoren erklären auf ungezählten Seiten, wie ihre Frameworks funktioniern. Sie schreiben sehr viel im Verhältnis zu dem, was sie erklären ;)

                  Ich erkläre auf einer einzigen A4-Seite, wie mein FW funktioniert, erkläre dabei nebenbei mod_perl und nenne in dem Zusammenhang eine Handvoll bekannter Design-Patterns die drin stecken ;)

                  was hinter dem Frontcontroller funktioniert, und ob der aus Apache-Sicht ein Client ist oder nicht. Das Pattern bezieht sich darauf, dass alle Requests über den Front-Controller gehen, ausnahmslos.

                  So ist das auch in meinem FW. Aber scheiß auf Design-Patterns ;)

                  Und im FrontController wird entschieden, wie zu verfahren ist.

                  Genau. Und: Was zu machen ist, das wissen die Subklassen. Btw., die kann ich auch erweitern, Beispiel von gestern:

                  /feedback.html        => class MVC::Feedback
                  /feedback_attach.html => class MVC::Feedback::Attach

                  In der Erweiterung wird nur die control()-Method überschrieben und das Template ist ein Anderes (Mailformular zum Senden von Mails mit Dateianlagen).

                  Die Zuordnung von Request /abc/def scheint mir bei Dir ähnlich wie im schon erläuterten ZF. Der Request-Path wird einer Funktion einer Klasse zugeordnet. Das ist aber (im ZF zumindest) schon eine Form von (Standard-)Routing.

                  Die Klassenbindung (URL <=> Class) ist der einzige Weg, ein FW skalierbar, überschaubar, wartungsfreundlich, teamgefällig und so zu bauen, dass zum Entwickeln von Erweiterungen Grundkenntnisse ausreichen. Da bin ich nicht der Einzige, der zu dieser Erkenntnis gelangt ist ;)

                  Btw., eine Factory, verbunden mit dem automatischen Laden weiterer Klassen und Methoden (Lazy Load, Lazy Creation), kriegt unter mod_perl eine ganz andere Dimension: Aus dem Dateisystem werden Sourcen NUR einmal geladen und kompiliert (also nicht beim Server-Start und auch nicht bei jedem Request, sondern nur beim Ersten Request entsprechend der Klassenbindung). Danach verbleibt der CODE im Hauptspeicher solange, bis der Apache neu gestartet wird. Es gibt Leute, die so ziemlich alles beim Apache-Start in den Hauptspeicher RAMmeln, kommen dann aber arg in Zeitnot, wenn dabei was schiefgehen sollte. Dann heißt es nämlich, Logs zu gucken und solange steht ALLES.

                  Schöne Grüße,
                    Horst, das Haselhuhn ;)