Ankündigung

Einklappen
Keine Ankündigung bisher.

Welches Entwurfsmuster für Netzwerkprotokollklasse?

Einklappen

Neue Werbung 2019

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

  • Welches Entwurfsmuster für Netzwerkprotokollklasse?

    Servus,

    ich hab hier ne kleine Denkblockade, ich muss in PHP eine Implementation eines Netzwerkprotolls schreiben.

    Dazu benötige ich eine Klasse mit die die Connection zum Server handelt und viele kleine Klassen die einen Befehl an den Server senden und dessen Antwort verarbeiten.

    Soweit lässt sich das alles wunderbar über das Verhaltensmuster "Command" lösen.
    Jetzt stellt sich mir allerdings die Frage wie ich von außen an die Antworten komme.
    Wäre es sinnvoll die Befehle per Factory zu instanzieren wobei die Factory gleichzeitig die Befehle speichert als History oder soll das ganze so bleiben und die Befehle einfach nur um eine weitere Methode erweitert werden welche die Antwort des Servers zurückgibt?

    Für ein paar Anregungen das vernünftig umzusetzen wäre ich dankbar.
    Gewisse Dinge behält man besser für sich, z.B. das man gewisse Dinge für sich behält.

  • #2
    Hallo HStev,

    ich würde in dieser Angelegenheit nicht krampfhaft nach einem Pattern suchen, sondern etwas mehr Pragmatismus walten lassen. Was du brauchst ist:

    * Eine Basis-Implementierung, die dir den Rahmen deiner API bereitstellt
    * Verschiedene Commands, die über deren API konfigurierbar sind
    * Standardisierte Basis-API, mit der man zu jedem Command jeweils ein Answer ziehen kann um die Antwort auf die jeweilige Anfrage abfangen kann

    Aussen drum noch ein bischen Exception- und Error-Handling und fertig.

    Beispiel:
    PHP-Code:
    class SendDataCommand extends AbstractCommand
    {
       ...
    }

    $conn = new NetworkLayer();
    $comm = new SendDataCommand();
    $comm->set*('...');
    $conn->executeCommand($comm);
    $ans $conn->getAnswer();
    echo 
    $ans->getMessage(); 
    ... oder wie auch immer!
    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
      Ja so in der Art hab ich das ja auch nur ich hab das Problem das meine Connection Klasse gleichzeitig die Command History verwaltet ... und da jedes Command die Connection im Construktor mitbekommt hab ich praktisch ein Array was immer auf sich selber zeigt ... beim Debuggen mit print_r oder var_export bekomme ich immer die Meldung das die Verschaltelung zu tief wäre.

      Dazu kommt noch das die Connection Class gleichzeitig Connection Handler, Command History Container und Command Factory ist und ich denke mir das in kein gutes Entwicklungskonzept.
      Gewisse Dinge behält man besser für sich, z.B. das man gewisse Dinge für sich behält.

      Kommentar


      • #4
        Zitat von HStev Beitrag anzeigen
        beim Debuggen mit print_r oder var_export bekomme ich immer die Meldung das die Verschaltelung zu tief wäre.
        Wenn du auf ner Testumgebungs arbeitest, kannst du ja mal deinem php ein xdebug gönnen, var_dump sollte dann imstande sein solche Verschachtelungen zu erkennen und nicht in die Unendlichkeit abzudrifften.
        [URL="http://www.robo47.net"]robo47.net[/URL] - Blog, Codeschnipsel und mehr
        | :arrow: [URL="http://www.robo47.net/blog/192-Caching-Libraries-and-Opcode-Caches-in-php-An-Overview"]Caching-Klassen und Opcode Caches in php[/URL] | :arrow: [URL="http://www.robo47.net/components"]Robo47 Components - PHP Library extending Zend Framework[/URL]

        Kommentar


        • #5
          Zitat von robo47 Beitrag anzeigen
          kannst du ja mal deinem php ein xdebug gönnen
          xdebug ist drinn nur leider versteht sich das Eclipse Debug Plugin nicht mit dem xdebug
          Gewisse Dinge behält man besser für sich, z.B. das man gewisse Dinge für sich behält.

          Kommentar


          • #6
            Eclipse mit PDT + XAMPP mit Xdebug - Developer's Guide
            [FONT="Book Antiqua"][I]"Nobody is as smart as everybody" - Kevin Kelly[/I]
            — The best things in life aren't things[/FONT]

            Kommentar


            • #7
              so ist es eingerichtet aber Eclipse hängt bei 19% Launching
              Gewisse Dinge behält man besser für sich, z.B. das man gewisse Dinge für sich behält.

              Kommentar


              • #8
                und da jedes Command die Connection im Construktor mitbekommt
                Warum muss das so sein? Wenn das Command doch der Connection übergeben wird (siehe mein Code), muss dass doch nicht im Konstruktor passieren, sondern der abstrakte Command kann dafür mit einem setConnection() aufwarten.

                Anders gesprochen: um wirklich absolut sicher zu gehen, sollte der Command nicht direkt von der Connection abhängen. So ein Design wäre im HTTP-Protokoll z.B. fatal.
                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


                • #9
                  Zitat von dr.e. Beitrag anzeigen
                  Warum muss das so sein? Wenn das Command doch der Connection übergeben wird (siehe mein Code), muss dass doch nicht im Konstruktor passieren, sondern der abstrakte Command kann dafür mit einem setConnection() aufwarten.
                  Ja ich hab das so gemacht da die Connection Klasse die grundsätzliche Kommunikation mit den Server verwaltet. Also die Klasse stellt Methoden bereit die das Command senden und die Raw Daten empfängt die wieder an das Command zurückgegeben werden wo dann die eigentliche Verarbeitung der Antwort stattfindet.
                  Gewisse Dinge behält man besser für sich, z.B. das man gewisse Dinge für sich behält.

                  Kommentar


                  • #10
                    Zitat von dr.e. Beitrag anzeigen
                    Anders gesprochen: um wirklich absolut sicher zu gehen, sollte der Command nicht direkt von der Connection abhängen. So ein Design wäre im HTTP-Protokoll z.B. fatal.
                    das must du mir noch mal genauer erläutern ich versuche grad das ganze anzupassen und erstelle mir dazu grad erstmal das UML aber mir will nicht so ganz einleuchten wozu das Comm Objekt dient ... wenn das Command die Connection bekommt sagen wir mal durch setConnection dann hängt es doch auch nicht von der Connection ab.

                    Das einzigste wo ich sage das es ein Fehler war ist die Command History direkt in der Connection feszuhalten.
                    Gewisse Dinge behält man besser für sich, z.B. das man gewisse Dinge für sich behält.

                    Kommentar


                    • #11
                      Hallo HStev,

                      wenn das Command die Connection bekommt sagen wir mal durch setConnection dann hängt es doch auch nicht von der Connection ab. Das einzigste wo ich sage das es ein Fehler war ist die Command History direkt in der Connection feszuhalten.
                      Eine direkte ABhängigkeit wäre dann gegeben, wenn die Connection den Command kennen muss um ihn ausführen zu können. Dass der Inhalt eines Commands irgendwann an die Connection gerät ist klar, nur sollte das die Connection-Klasse regeln. So kannst du beliebige Commands einhängen.

                      Nach längerem Nachdenken würde ich fast sagen, dass noch eine dritte Klasse ins Spiel gebracht werden sollte, die das Ganze steuert. Connection und Command sind in diesem Fall dann passiv und werden von einer Networking-Komponente gesteuert, der man eine beliebige Connection und einen beliebigen Command geben kann. So wärst du noch unabhängiger und könntest z.B. nicht nur HTTP, sondern z.B. auch FTP addressieren.

                      Back to topic: Zeig mir mal ein UML, daran kann man sicher einfacher diskutieren.
                      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


                      • #12
                        Zitat von dr.e. Beitrag anzeigen
                        Nach längerem Nachdenken würde ich fast sagen, dass noch eine dritte Klasse ins Spiel gebracht werden sollte, die das Ganze steuert. Connection und Command sind in diesem Fall dann passiv und werden von einer Networking-Komponente gesteuert, der man eine beliebige Connection und einen beliebigen Command geben kann. So wärst du noch unabhängiger und könntest z.B. nicht nur HTTP, sondern z.B. auch FTP addressieren.
                        Achso verstehe du meinst also eine Klasse die den reinen Socket und dessen Funktionen bereitstellt. Eine Klasse die die Communikation handelt und die jeweiligen Unterklassen für die Commands ... hinzu würden dann noch die entsprechenden "Besucher" kommen die dann entweder die Daten speichern oder darstellen.

                        Naja in diesen Fall wird es bei einen Protokoll bleiben, es handelt sich hierbei um das svdrp Protokoll des VDR's in der Version 1.5 es kommt höchstens zu einer Erweiterung oder Änderung der Befehle deshalb will ich das ganze Klassen basiert haben.

                        SVDRP - VDR Wiki
                        Gewisse Dinge behält man besser für sich, z.B. das man gewisse Dinge für sich behält.

                        Kommentar


                        • #13
                          So richtig fit bin ich in UML noch nicht ich arbeite mich grad erst ein.
                          Aber ich hoffe das es einigermaßen verständlich ist.

                          so hab ich mir das bisher gedacht, da PHP Klassen als Referenz übergibt brauche ich im Prinzip den Handler nicht.



                          ps: ist übrigens das 1. Projekt wo ich eine sinnvolle Verwendung des destructors gefunden habe, der Destructor sendet in diesen Fall noch ein QUIT an den Server damit der Server nicht ins Timeout läuft und die Connection sauber geschlossen wird.
                          Gewisse Dinge behält man besser für sich, z.B. das man gewisse Dinge für sich behält.

                          Kommentar


                          • #14
                            Hallo HStev,

                            hast du mal ein Code-Beispiel dazu?

                            Was ich nicht ganz nachvollziehen kann:
                            * Warum hat Connection::execute() ein Argument-Array dabei? Warum bildest du das nicht über den Command ab?
                            * Warum führtst du kein Answer-Objekt ein? Einen String zurückzubekommen ist problematisch, da dieser wieder geparst werden muss.
                            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


                            • #15
                              Zitat von dr.e. Beitrag anzeigen
                              Hallo HStev,

                              hast du mal ein Code-Beispiel dazu?
                              ist mittlerweile schon recht umfangreich welchen Teil willst genau sehen

                              Zitat von dr.e. Beitrag anzeigen
                              Was ich nicht ganz nachvollziehen kann:
                              * Warum hat Connection::execute() ein Argument-Array dabei? Warum bildest du das nicht über den Command ab?
                              Da bin ich mir halt noch nicht so ganz im klaren wie ich das lösen soll.
                              Einige der Befehle erwarten 0-3 Parameter. Und es ist auch eigentlich kein Array sonderen soll eine Variable Parameter-Liste sein und ich frag die Parameter daher mit func_get_args ab und gib die dann nur direkt weiter an das Command.

                              Zitat von dr.e. Beitrag anzeigen
                              * Warum führtst du kein Answer-Objekt ein? Einen String zurückzubekommen ist problematisch, da dieser wieder geparst werden muss.
                              Wie meinst du das? Die Antwort für jeden Befehl sieht anders und muss anders geparsed bzw. verarbeitet werden.
                              Die Daten die ankommen sind im Prinzip
                              Einzeilige Antwort:
                              3 stelliger Code gefolgt von einen Datenstring und Carage Return Line Feed
                              Mehrzeilige Antwort:
                              3 stelliger Code - Zeilennummer Datenstring Carage Return
                              Letzte Zeile wird abgeschlossen mit CR LF

                              Und der Datenstring ist selber auch noch mal unterteilt je nach Befehl zb. der Befehl LSTC holt alle Kanale und gibt deren Daten nach den Schema aus wie sie in der channels.conf angegeben sind.
                              Channels.conf - VDR Wiki

                              Das würde dann im Prinzip bedeuten das ich für jeden Befehl noch ein AnswerObjekt einführen muss was aber eigentlich sinnlos wäre weil dann bräucht das Command-Object nicht weil beim senden ist nicht viel zu beachten.
                              Gewisse Dinge behält man besser für sich, z.B. das man gewisse Dinge für sich behält.

                              Kommentar

                              Lädt...
                              X