Ankündigung

Einklappen
Keine Ankündigung bisher.

[Frontcontroller] Generischer Datenaustausch

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • [Frontcontroller] Generischer Datenaustausch

    Hallo zusammen,

    grob gesprochen geht es mir um den Austausch von Informationen zwischen einer Froncontroller-Action und dem Document-Controller der meinen View aufbaut.

    Im Detail:
    Innerhalb eines Backend gibt es die Möglichkeit eine Datenbank-Sicherung anzufertigen. Per Klick auf den entsprechenden Menüpunkt wird dem Benutzer ein Button angeboten (View 1), mit dem er das Backup starten kann. Klickt er auf diesen, wird die Backup-Action ausgeführt und der View "Bestaetigung" (View 2) angezeigt. Das passiert intern so:
    • - POST gegen die index.php mit den Frontcontroller-Action-Anweisungen
    • - Initialisierung des Frontcontrollers
    • - Ausführen der Backup-Action[list:6a986edfb9]- Diese initialisiert die Business-Schicht (den zentralen Manager)
    • - und führt das Backup mit Hilfe det Datenschicht aus
    • - Ergebnis des Backup-Vorgangs ist der Dateinamen des Backup-Files
    [/list:u:6a986edfb9]
    • - Aufbau der Seite
    • - Transformation der Seite
    • - Ausführen des DocumentControllers "backup_v1_controller", der die
      Bestätigungs-Seite (View 2) anzeigt.


    Herausforderung ist nun, dem View in sinnvoller Art uns Weise den Namen des Backup-Files bekannt zu geben. Proprietärer Ansatz wäre es, ein Attribut der Business-Schicht während der Ausführung der Action zu füllen und im Document Controlelr wieder abzufragen. Das ist jedoch nicht befriedigend, da es kein generischer Ansatz ist. Das Listener-Pattern ist in diesem Fall nicht zielführend, da der Objektbaum der Seite zur Ausführungszeit der Action noch nicht existiert und die Instanz des Document Controllers auch nicht. Zweiter Ansatz ist eine Message Queue, die sowohl die Action schreiben, als auch der Document Controller lesen kann. Dritter Ansatz ist es in der Business-Schicht einen Container zu erstellen, in die unterschiedliche Teilnehmer Werte hinterlegen können.

    Welche Lösungsmöglichkeiten sehr ihr hier? Welches Design-Pattern könnte hier helfen?


    Grüße,
    Dr,E,
    Viele Grüße,
    Dr.E.

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    1. Think about software design [B]before[/B] you start to write code!
    2. Discuss and review it together with [B]experts[/B]!
    3. Choose [B]good[/B] tools (-> [URL="http://adventure-php-framework.org/Seite/088-Why-APF"]Adventure PHP Framework (APF)[/URL][URL="http://adventure-php-framework.org"][/URL])!
    4. Write [I][B]clean and reusable[/B][/I] software only!
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  • #2
    Hallo zusammen,

    nachdem ich auf meinen Post keine Antwort bekommen habe, gehe ich davon aus, dass der Stoff von mir entweder nicht gut genug erklärt war, oder es keiner versteht.

    In der Zwischenzeit habe ich ein bischen recherchiert (Martin Fowler & Co.) und mir ein Konzept überlegt. Dieses sieht folgendes vor:

    - Business-Schicht wurde um die Komponente "viewManager" erweitert. Dieser
    verwaltet zentral (Singleton!) die View-Informationen in sog. "viewObject"s.
    - Ein "viewObject" kann per Konfiguration initialisiert werden und es besteht damit die
    Möglichkeit Standard-Views zu definieren (z.B. Auswahlformular).

    Damit ist möglich, dass eine Action nach Ausführung den View ändert und weitere "ViewAttributes" bekannt gibt. Hier können von der Action erzeugte Attribute oder Input-Attribute der Action publiziert werden. Die Präsentations-Schicht (Document Controller) kann diese dann zum Aufbau des richtigen Views verwenden und den View ggf. mit den im "viewObject" enthaltenen Informationen füllen. Der Ablauf des
    DB-Backups sieht dann wie folgt aus (gekürzt):

    - Action erzeugt ein DB-Backup
    - Action holt sich das "viewObject" für den entsprechenden View
    - Action füllt die Attribute es "viewObjects" mit dem Backup-Dateinamen und einigen
    weiteren Daten

    - Document Controller zieht sich das entsprechende "viewObject"
    - Document Controller baut den im "viewObject" beschriebenen View auf und füllt
    diesen mit Attributen desselben (z.B. Name des Backup-Files)

    Da die Business-Komponente "viewManager" generisch ist, kann diese auch für alle weiteren Teile der Software verwendet werden. Voraussetzung ist, dass diese immer singleton instanziiert ist.

    Schade, dass so wenig Response kam, denn das Thema ist wirklich sehr interessant. Den Aussagen nach zu urteilen müssten einige hier im Board sicher das Know-How haben... Sollte jemand trotzdem Interesse an derartigen Konzepten (Web-Applikationen im Page- und Frontcontroller-Pattern) haben, so möge er sich einfach melden.
    Viele Grüße,
    Dr.E.

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    1. Think about software design [B]before[/B] you start to write code!
    2. Discuss and review it together with [B]experts[/B]!
    3. Choose [B]good[/B] tools (-> [URL="http://adventure-php-framework.org/Seite/088-Why-APF"]Adventure PHP Framework (APF)[/URL][URL="http://adventure-php-framework.org"][/URL])!
    4. Write [I][B]clean and reusable[/B][/I] software only!
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Kommentar


    • #3
      Hallo zusammen,

      ich möchte noch eine andere Lösung (=sauberste Lösung) dokumentieren, falls mal jemand über das Thema stolpern sollte.

      Vorteil einer Frontcontroller-basierten Anwendung ist, dass das Model zur Transformations-Zeit bereits aufgebaut ist und die zur Transformation der Seite enthaltenen Informationen schon enthält. Obige Lösung würde die Model-Informationen doppelt halten, da sie in einem viewManager und in der Frontcontroller-Action stehen. Deshalb muss der Frontcontroller (wird Singleton instanziiert) eine Methode kennen, die einem eine Action (als Referenz) per Name (getActionByName()) zurückgibt und über die der DocumentController auf das Model zugreifen kann. Damit hat der DocumentController zur Transformation alle nötigen Informationen und kann den View aufbauen. Um eine noch sauberer Implementierung zu gewährleisten kapselt die Business-Schicht der Anwendung das getActionByName() nochmal und tritt gegenüber der Präsentations-Schicht als einziger Kontaktpunkt aus. Hierzu muss die Business-Schicht einfach "nochmal" ein getActionByName() implementieren und darin einfach den hier nochmal Singleton instanziierten Frontcontroller verwenden und die Action gemäß dem übergebenen Namen zurückliefern (als Referenz).

      Sollten noch Fragen auftauchen -> PN.
      Viele Grüße,
      Dr.E.

      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      1. Think about software design [B]before[/B] you start to write code!
      2. Discuss and review it together with [B]experts[/B]!
      3. Choose [B]good[/B] tools (-> [URL="http://adventure-php-framework.org/Seite/088-Why-APF"]Adventure PHP Framework (APF)[/URL][URL="http://adventure-php-framework.org"][/URL])!
      4. Write [I][B]clean and reusable[/B][/I] software only!
      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

      Kommentar


      • #4
        Jetzt hab ich mir das ganze durchgelesen und muss sagen, dass ich hier nichts gewinnbringendes einbringen könnte. Meine MVC-Erfahrung ist da doch eher mager und beschränken sich auf die Standard-Ausführungen.

        Ist aber sicher eine ganz interessante Sache - wo hast du die Infos denn zusammengesammelt, gibts irgendwelche Blogs oder Wiki-Seiten, die zu empfehlen sind?

        Kommentar


        • #5
          Hallo Zergling,

          danke für dein Statement.

          Ist aber sicher eine ganz interessante Sache - wo hast du die Infos denn zusammengesammelt, gibts irgendwelche Blogs oder Wiki-Seiten, die zu empfehlen sind?
          Der Weg dahin war nicht ganz einfach. Ich hab mir durch unmengen von Literatir gewälzt, viele Anwendungen implementiert und mir immer wieder die Frage gestellt, wie es besser geht und wie man dynamische Webanwenungen wirklich effektiv zu gestalten. Es ging immer wieder um Wiederverwendbarkeit, saubere Implementierung und Effizienzsteigerung.
          Ich hab in den Anfängen eine Funktionsbibliothek erstellt, die sich mit Standard-Problemen beschäftigt (u.A. Fileupload; hatte dazu mal vor Urzeiten ein Tutorial im Dr.Web-Forum eingestellt). Problem beim Skripting ist, dass man zwar einige oder viele Dinge eingermaßen sauber erstellen kann, nur verfällt man immer wieder dem Problem, Dinge doppelt machen zu müssen. Weiteres Thema war für mich die Erstellung eines CMS, in dem man Module (Terminkalender, Gästebuch, et. al.) per Tag einbinden kann und diese vom Text-Parser ausgeführt werden. Hier kommt man mit Skripting an seine Grenzen. Die damals konsumierte Literatur führte mich dann zum objektorientierten Entwurfs- und Programmier-Ansatz, da man dort per Vererbung Funktionalitäten in beliebige Richtungen weiterentwickeln kann. Aus der Funktionsbibliothek wurde allmählich eine Klassensammlung (FilesystemManager, ConfigurationManager, et. al.) die mitlererweile zu einem recht ansehnlichen Framework gehören, die die Grundlage für die Implementierung von Web-Anwendungen im Page- und Frontcontroller-Pattern und der 3-Schicht-Architektur bereit stellen. Somit ist es möglich eine Footer-Leiste mit Drucken, Weiterempfehlen et. al. auf mehreren Seiten einzubinden und im CD der Seite zu formatieren ohne Teile des Codes zu ändern. U.a. gibt es auch einen Template-Parser, der aus einem Template eine Objektbaum einer Seite, quasi ein eigenes DOM aufbaut und man dort die Möglichkeit hat in einem bestehenden Template per XML-Tag eine weitere Anwendung (z.B. Footer-Leiste) einzubinden. Hilfreich und immer viel zittiert sind in meinen Beiträgen die Pattern. Ich halte diese aber für sehr wichtig, da man nicht lange über Standard-Probleme nachdenken muss, sondern einfach eine Lösung hat und muss diese nur noch implementieren. Wie schon oft hier angesprochen, hat PHP sicher seine Schwächen, aber wenn man sich konzeptionell die richtigen Gedanken macht, kann man auch mit PHP echte Anwendungen schreiben. Wenn hier Bedarf an Erklärung besteht, oder sich jemand für eine Beispiel-Anwendung interessiert, kann er sich gerne melden, ich hab ausreichend Info's und Code, den ich gerne zur Verfügung stelle.


          Was Literatur angeht:

          Hilfreich sind sicher die WIKI-Seiten:

          - http://de.wikipedia.org/wiki/Entwurfsmuster
          - http://de.wikipedia.org/wiki/Martin_Fowler
          - http://de.wikipedia.org/wiki/Mehrschichtigkeit
          - http://de.wikipedia.org/wiki/Dreischichtige_Architektur
          - http://de.wikipedia.org/wiki/Anwendungsdom%C3%A4ne

          Insbesondere als Bücher sind empfehlenswert:

          - Martin Fowler: UML Distilled
          - Martin Fowler: Patterns of Enterprise Application
          - Christoph Reeg: Datenbanken, PHP und MySQL

          Und natürlich:

          - Manuals lesen
          - Manuals lesen
          - Manuals lesen

          - Ausprobieren
          - Sich durchbeißen
          - Über ein Problem nachdenken



          Sollte der Bedarf an Literatur (in elektronischer Form) bestehen -> PM.


          Für Diskussionen bin ich jederzeit offen...
          Viele Grüße,
          Dr.E.

          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          1. Think about software design [B]before[/B] you start to write code!
          2. Discuss and review it together with [B]experts[/B]!
          3. Choose [B]good[/B] tools (-> [URL="http://adventure-php-framework.org/Seite/088-Why-APF"]Adventure PHP Framework (APF)[/URL][URL="http://adventure-php-framework.org"][/URL])!
          4. Write [I][B]clean and reusable[/B][/I] software only!
          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

          Kommentar


          • #6
            Kannst du das ganze mal am Beispiel der Backup-Funktionalität hier gekürzt posten. Würde mich interessieren wie das dann konkret gelöst wird.

            Kommentar


            • #7
              Hallo Zergling,

              dem Wunsch komme ich gerne nach. Ich versuche es so kurz wie möglich zu halten...

              Folgende Komponenten sind am Geschehen beteiligt:

              - Frontcontroller:
              Stellt die Funktionalität bereit, dass vor dem Transformieren einer Seite die Business-Schicht bereits aufgebaut wird. Somit steht das Model der Anwendung zum Zeitpunkt der Transformation der Seite bereits zur Verfügung und die Präsentations-Schicht muss nur noch gemäß den Model-Informationen die Views erzeugen.

              - Pagecontroller
              Kapselt verschiedene Präsentations-Schicht-Funktionalitöten, wie das Parsen von Templates, Ausführen von im Interface eines Objektbaum der Seite definierten Objekts...

              - Actions
              Das sind FrontController-Actions, die zur Business-Schicht gehören und bestimmte Aktionen (hier das Backup) ausführen und das Model verändern (Informationen hinzufügen)

              - Documentcontroller
              Controller, die an Hand der Model-Informationen den View aufbauen. Es gint Standard-(Interface)-Methoden, die jeder DocumentController implementieren muss. Hier ist das transformContent(). Diese wird beim rekursiven Transformieren des Objektbaums der Seite auf jeden DocumentController aufgerufen und generiert den View.


              In Code bedeutet das folgendes:

              index.php
              PHP-Code:
                 $fC = &Singleton::getInstance('Frontcontroller');
                 
              $fC->set('Context','sites::weiterbildungsveranstaltung');
                 
              $fC->start('namespace::to::myapp::pres::templates','main_template');
              ?> 
              Die index.php instanziiert den Frontcontroller. Dieser parst die URL nach Action-Anweisungen der Form {namespace}-action:{action}={params} und erzeugt die zugehörigen Action-Objekte. Ist die Backup-Action gefragt, so instanziiert er diese und führt die run()-Methode aus.


              Frontcontroller.php

              PHP-Code:
                    function start($Namespace,$Template){

                       
              $this->__parseActions();

                       if(
              $this->__EnablePermanentActions == true){
                          
              $this->__loadPermanentActions();
                        
              // end if
                       
              }

                       
              $Page = new Page();
                       
              $Page->set('Context',$this->__Context);
                       
              $Page->loadDesign($Namespace,$Template);

                       
              $this->__runActions('permanentpre');
                       
              $this->__runActions('pre');

                       
              $PageContent $Page->transform();

                       
              $this->__runActions('post');
                       
              $this->__runActions('permanentpost');

                       echo 
              $PageContent;

                     
              // end function
                    
              }

              ?> 
              BackupDatabase.php

              PHP-Code:
                    function BackupDatabase(){
                       
              $this->__M = & Singleton::getInstance('wvManager');
                     
              // end function
                    
              }

                    function 
              run(){

                       if(
              $this->__Input->getAttribute('view') == 'backup'){

                          
              $BackupDatei $this->__M->sichereDatenbank();

                          
              $this->__Input->setAttribute('BackupFileName',$BackupDatei);
                          
              $this->__Input->setAttribute('view','bestaetigung');

                        
              // end if
                       
              }

                     
              // end function
                    
              }
              ?> 
              In der Action (Klasse "BackupDatabase") wird dann die Business-Schicht (Klasse "wvManager") instanziiert (immer Singleton!) und das Backup ausgeführt. Zusäzlich werden die relevanten Informationen in das Input-Objekt geschreiben (=Model), damit die Präsentations-Schicht weiß, was zu tun ist.


              backup_v1_controller.php

              PHP-Code:
                    function transformContent(){

                       
              $Action = & $this->__M->getActionByName('Backup');
                       
              $Input = & $Action->getInput();

                       if(
              $Input->getAttribute('view') == 'auswahl'){
                          
              $Template__Formular = & $this->__getTemplate('Formular');
                          
              $this->setPlaceHolder('Inhalt',$Template__Formular->transformTemplate());
                        
              // end if
                       
              }

                       if(
              $Input->getAttribute('view') == 'bestaetigung'){
                          
              $this->setPlaceHolder('Inhalt',$this->__generiereBestaetigung($Input->getAttribute('BackupFileName')));
                        
              // end if
                       
              }

                     
              // end function
                    
              }

                    function 
              __generiereBestaetigung($BackupFileName){

                       
              $Action = & $this->__M->getActionByName('Backup');
                       
              $Input = & $Action->getInput();
                       
              $BackupFileName $Input->getAttribute('BackupFileName');

                       
              $Template = & $this->__getTemplate('Bestaetigung');
                       
              $Template->setPlaceHolder('BackupLink',BACKUP__URL_PATH.'/'.$BackupFileName);

                       
              $Template->setPlaceHolder('BackupDatei',$BackupFileName);

                       return 
              $Template->transformTemplate();

                     }
              ?> 
              In der Datei des Document Controllers werden einige Methoden der API verwendet. Hier die wichtigste: __getTemplate(). Sie stammt vom Objekt Document, von dem jeder Baum-Knoten ableitet. Innderhalb des Contents eines Dockuments können Templates der Form

              Code:
              <html:template name="Bestaetigung">
                Die Sicherung wurde erfolgreich durchgeführt. Sie können die aktuelle Sicherungsdatei unter folgendem Link per
                "Speichern unter" herunterladen:
                
              
                
              
                
              
                <div style="text-align: center;">
                  Sicherungsdatei:" title="Datei <template:placeholder name="BackupDatei" /> bitte per 'Speichern unter' downloaden!"><template:placeholder name="BackupDatei" />
                </div>
              </html:template>
              eingebettet sein. Die Methode __generiereBestaetigung() benutzt das angezeigte Template um die Bestätigungs-Nachricht im View auszugeben.


              Ich hoffe das war knapp genug (Kommentare wurden aus dem Code weitestgehend entfernt). Essentiell ist eben, dass der Aufbau des DOM's der Seite über die Logik des PageControllers passiert, der die Designs parst und nach Tags durchsucht. Man kann beispielsweise in eine Seite per

              Code:
              <core::importdesign namespace="" template="" />
              in ein vorhandenes Document ein weiteres als Kind-Document einhängen. Beispiel hierfür wäre die Content- und Menü-Area einer Seite. Jeders dieser Document's hat wiederum seinen DocumentController (bei Bedarf; kann auch mal keinen haben, wenn keine logische Funktionalität im Design steckt), der logische Funktion in das Template bringt.

              Ich kann gerne mal die API-Dokumentation zur Verfügung stellen, bzw. ein UML hinzufügen, dann wird klarer, was hier passiert.


              Any questions left?
              Viele Grüße,
              Dr.E.

              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
              1. Think about software design [B]before[/B] you start to write code!
              2. Discuss and review it together with [B]experts[/B]!
              3. Choose [B]good[/B] tools (-> [URL="http://adventure-php-framework.org/Seite/088-Why-APF"]Adventure PHP Framework (APF)[/URL][URL="http://adventure-php-framework.org"][/URL])!
              4. Write [I][B]clean and reusable[/B][/I] software only!
              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

              Kommentar


              • #8
                man ey für leute wie dich sollte es echt eine kategorie tiefer als anfänger geben
                aber deine frage scheint nicht beantwortet .. oder ist jetzt alles klar?
                wenn nicht bitte nochmal frage formulieren. wenn ichs richtig verstanden habe würd ich ne art masterklasse schreiben die die werte bzw einzelnen parameter für die sets() je nach fall zuweist
                [FONT="Book Antiqua"][I]"Nobody is as smart as everybody" - Kevin Kelly[/I]
                — The best things in life aren't things[/FONT]

                Kommentar


                • #9
                  Stecke grad in den Klausuren, schau mir das am Wochenende mal an.

                  Kommentar


                  • #10
                    Hallo phpdummi,

                    > man ey für leute wie dich sollte es echt eine kategorie tiefer als
                    > anfänger geben
                    ich persönlich denke nicht, dass das eine Anfängerfrage ist, sondern eine Frage, die sich mit dem Software-Design nach bekannten Entwurfsmustern beschäftigt. Viele der Anfänger haben sicher von Pattern noch nichts gehört...


                    > aber deine frage scheint nicht beantwortet .. oder ist jetzt alles klar?
                    Das solltest du aus meiner Beschreibung gelesen haben. Meine Frage ist beantwortet, bzw. habe ich mir diese selbst und mit Hilfe von Kollegen klar gemacht.


                    > wenn nicht bitte nochmal frage formulieren. wenn ichs richtig
                    > verstanden habe würd ich ne art masterklasse schreiben die die werte
                    > bzw einzelnen parameter für die sets() je nach fall zuweist
                    Ich muss dich entäuschen, das hat mit einer "Masterklasse" nicht zu tun. Sicher leite ich meine Klassen von einer abstrakten Klasse "coreObject" ab, die die Basis-Attribute und Methoden definiert, jedoch geht es hier im die Implementierung eines Frontcontrollers. Lies dir mal die Inhalte zu meinen Links durch, dann siehst du klarer.
                    Viele Grüße,
                    Dr.E.

                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                    1. Think about software design [B]before[/B] you start to write code!
                    2. Discuss and review it together with [B]experts[/B]!
                    3. Choose [B]good[/B] tools (-> [URL="http://adventure-php-framework.org/Seite/088-Why-APF"]Adventure PHP Framework (APF)[/URL][URL="http://adventure-php-framework.org"][/URL])!
                    4. Write [I][B]clean and reusable[/B][/I] software only!
                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

                    Kommentar


                    • #11
                      Zitat von Zergling
                      Stecke grad in den Klausuren, schau mir das am Wochenende mal an.
                      Fein. Freu mich auf dein Feedback.
                      Viele Grüße,
                      Dr.E.

                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                      1. Think about software design [B]before[/B] you start to write code!
                      2. Discuss and review it together with [B]experts[/B]!
                      3. Choose [B]good[/B] tools (-> [URL="http://adventure-php-framework.org/Seite/088-Why-APF"]Adventure PHP Framework (APF)[/URL][URL="http://adventure-php-framework.org"][/URL])!
                      4. Write [I][B]clean and reusable[/B][/I] software only!
                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

                      Kommentar

                      Lädt...
                      X