Stefan: Design Pattern für Container-Element gesucht

Hallo

Ich habe ein Container-Element, welches verschiedene Panels anzeigen kann. Es darf aber nur jeweils genau ein Panel angezeigt werden. Wird ein Panel angezeigt, muss zudem das zuvor angezeigte Element entfernt werden. Ich bin mir ziemlich sicher dass es dafür ein Design Pattern gibt, nur finde ich es nicht...

Das ganze wird für ein Javascript (Mit objektorientiertem Ansatz) benötigt, welches Kontrolliert, welches Panel(DIV) gerade angezeigt wird.

Gruss Stefan

  1. Hi,

    Ich habe ein Container-Element, welches verschiedene Panels anzeigen kann. Es darf aber nur jeweils genau ein Panel angezeigt werden. Wird ein Panel angezeigt, muss zudem das zuvor angezeigte Element entfernt werden. Ich bin mir ziemlich sicher dass es dafür ein Design Pattern gibt, nur finde ich es nicht...

    ich hab das Gang-of-Four-Buch gerade nicht zur Hand, aber ehrlich gesagt finde ich den Namen des Patterns auch nicht so wichtig :-)

    Das ganze wird für ein Javascript (Mit objektorientiertem Ansatz) benötigt, welches Kontrolliert, welches Panel(DIV) gerade angezeigt wird.

    Du kannst dem Container-Element (bzw. dessen DOM-Objekt) Methoden wie z.B. setPanel() hinzufügen. Du kannst die Schnittstelle auf vielerlei Arten aufbauen: Übergabe der Nummer des Panels, des Panel-Objekts, des Namens usw. Außerdem könnte sich ein setNextPanel() und setPreviousPanel() anbieten, ggf. mit (optionalem) Parameter, ob man "im Kreis" gehen kann oder nicht. Der Container merkt sich, wo er ist und wie viele Panel vorliegen - das ist im Grunde schon alles.

    Hilft Dir das weiter, oder brauchst Du wirklich den Namen eines Patterns?

    Cheatah

    --
    X-Self-Code: sh:( fo:} ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
    X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
    X-Will-Answer-Email: No
    X-Please-Search-Archive-First: Absolutely Yes
    1. Hi,

      Du kannst dem Container-Element (bzw. dessen DOM-Objekt) Methoden wie z.B. setPanel() hinzufügen. Du kannst die Schnittstelle auf vielerlei Arten aufbauen: Übergabe der Nummer des Panels, des Panel-Objekts, des Namens usw. Außerdem könnte sich ein setNextPanel() und setPreviousPanel() anbieten, ggf. mit (optionalem) Parameter, ob man "im Kreis" gehen kann oder nicht. Der Container merkt sich, wo er ist und wie viele Panel vorliegen - das ist im Grunde schon alles.

      Hilft Dir das weiter, oder brauchst Du wirklich den Namen eines Patterns?

      Hilft mir weiter;-)

      Danke.

      Viele Grüsse
      Stefan

      1. gruss Stefan,

        Du kannst dem Container-Element (bzw. dessen DOM-Objekt) Methoden
        wie z.B. setPanel() hinzufügen. Du kannst die Schnittstelle auf vielerlei
        Arten aufbauen: Übergabe der Nummer des Panels, des Panel-Objekts,
        des Namens usw. Außerdem könnte sich ein setNextPanel() und
        setPreviousPanel() anbieten, ggf. mit (optionalem) Parameter, ob man
        "im Kreis" gehen kann oder nicht. Der Container merkt sich, wo er ist
        und wie viele Panel vorliegen - das ist im Grunde schon alles.

        Hilft Dir das weiter, oder brauchst Du wirklich den Namen eines Patterns?

        Hilft mir weiter;-)

        ich bin ja auch nur »interessierter laie«, aber was Cheatah da
           beschreibt, klingt nach "controller"(?) - und jetzt? - das hilft
           Dir keinesfalls weiter, weil Du die konkrete implementierung
           immer noch von hand vornehmen musst.

        ich glaube auch, dass Cheatah Dir genau das sagen wollte und
           Dir deshalb den namen listig unterschlagen hat ;-)

        so long - peterS. - pseliger@gmx.net

        --
        »Because objects in JavaScript are so flexible, you will want to think differently about class hierarchies.
        Deep hierarchies are inappropriate. Shallow hierarchies are efficient and expressive.« - Douglas Crockford
        ie:( fl:) br:> va:( ls:& fo:) rl:| n3;} n4:} ss:} de:µ js:} mo:? zu:]
        1. Hi,

          habe eben versucht sowas zu implementieren:

            
          function Container() {  
           var container = new Array();  
           this.add = function(panel) {  
            container[panel.id] = panel;  
           }  
           this.remove = function(panel) {  
            container[panel.id] = null;  
           }  
            
           this.setPanel = function(id) {  
            for (panel in container) {  
            
              // TEST  
              alert(panel);  
            
             if(panel.id === id) {  
              panel.display();  
             }else{  
              panel.hide();  
             }  
            }  
           }  
          }  
            
          function Panel(id) {  
           this.id = id;  
           this.display = function() {  
            $(this.id).style.display = 'block';  
           }  
           this.hide = function() {  
            $(this.id).style.display = 'none';  
           }  
          }  
          function ConcretePanel(id) {  
          }  
          LoginPanel.prototype = new Panel();  
          
          

          Ich verstehe nicht warum bei // TEST im Code hier die möglichen Funktionen vom Array ausgegeben werden (und am schluss das hinzugefügte Panel)? Ich möchte doch nur die konkreten Panel ausgeben...

          Viele Grüsse
          Stefan

          1. gruss Stefan,

            ...
            Ich verstehe nicht warum bei // TEST im Code hier die möglichen Funktionen vom
            Array ausgegeben werden (und am schluss das hinzugefügte Panel)? Ich möchte doch
            nur die konkreten Panel ausgeben...
            ...

            function Container() {

            var container = new Array();

            //  aha, ein [Array]-objekt ...

            this.add = function(panel) {
              container[panel.id] = panel;

            //   ... warum ein array, obwohl Du "container" als [Object]-objekt verwendest.

            }

            //  };

            this.remove = function(panel) {
              container[panel.id] = null;

            //   delete container[panel.id];

            }

            //  };

            this.setPanel = function(id) {
              for (panel in container) {

            //   "container" ist sowohl [array] als auch [object] - "for ... in" erfasst immer
            //   alle objekteigenschaften, die enumerierbar sind - also sowohl alle sichtbaren
            //   eigenschaften des arrays "container" als auch die des objekts "container".

            // TEST
                alert(panel);

            if(panel.id === id) {
                panel.display();
               }else{
                panel.hide();
               }
              }
            }
            }

            // };

            
            > ...  
              
              
               so long - peterS. - pseliger@gmx.net  
              
              
            
            -- 
            »Because objects in JavaScript are so flexible, you will want to think differently about class hierarchies.  
            Deep hierarchies are inappropriate. Shallow hierarchies are efficient and expressive.« - [Douglas Crockford](http://javascript.crockford.com/)  
              
            ie:( fl:) br:> va:( ls:& fo:) rl:| n3;} n4:} ss:} de:µ js:} mo:? zu:]
            
            1. Hallo

              [code lang=javascript]
              function Container() {

              var container = new Array();

              //  aha, ein [Array]-objekt ...

              this.add = function(panel) {
                container[panel.id] = panel;

              //   ... warum ein array, obwohl Du "container" als [Object]-objekt verwendest.

              Ich verstehe nicht. Ich muss ja ein Array benutzen um irgendwo die Panels ablegen zu können.

              }
              //  };

              this.remove = function(panel) {
                container[panel.id] = null;

              //   delete container[panel.id];

              }
              //  };

              Ist das besser als = null?

              this.setPanel = function(id) {
                for (panel in container) {

              //   "container" ist sowohl [array] als auch [object] - "for ... in" erfasst immer
              //   alle objekteigenschaften, die enumerierbar sind - also sowohl alle *sichtbaren*
              //   eigenschaften des arrays "container" als auch die des objekts "container".

              Und wie gelingt es mir, nur die Panels auszulesen?

              Gruss Stefan

              1. hallo again Stefan,

                ...

                this.remove = function(panel) {

                container[panel.id] = null;

                //   delete container[panel.id];

                }
                //  };

                
                >   
                > Ist das besser als = null?  
                  
                   nach der \*reinen lehre\* schon. der [null] wert regt in diesem fall  
                   den garbage collector nicht dazu an, endgueltig aufzuraeumen, da  
                   sich das private "container" objekt permanent im scope seines  
                   [Container]-objekts befindet (solange letztgenanntes existiert).  
                  
                
                > ...  
                > Und wie gelingt es mir, nur die Panels auszulesen?  
                  
                  
                   versuch:  
                  
                  
                ~~~javascript
                var Container = function () {  
                  
                  var i, panels = [];  
                  
                  this.addPanel = function (panel) {  
                    panels.push(panel);  
                  };  
                  this.removePanel = function (panel) {  
                  
                    for (i=0; i<panels.length; ++i) {  
                      if (panels[i].id == panel.id) {  
                        break;  
                      }  
                    }  
                    panels = (panels.slice(0, i)).concat(panels.slice(i+1)); // ungetestet!  
                  };  
                  this.setPanel = function (id) {  
                  
                    for (i=0; i<panels.length; ++i) {  
                    //alert(panels[i]);  
                      if (panel.id == id) {  
                        panel.display();  
                      } else {  
                        panel.hide();  
                      }  
                    }  
                  };  
                };  
                  
                var Panel = function (id) {  
                  
                  this.id = id;  
                  
                  this.display = function () {  
                    $(this.id).style.display = "block";  
                  //$(this.id).style.display = ""; // stellt den default wieder her;  
                  };  
                  this.hide = function () {  
                    $(this.id).style.display = "none";  
                  };  
                };
                

                so long - peterS. - pseliger@gmx.net

                --
                »Because objects in JavaScript are so flexible, you will want to think differently about class hierarchies.
                Deep hierarchies are inappropriate. Shallow hierarchies are efficient and expressive.« - Douglas Crockford
                ie:( fl:) br:> va:( ls:& fo:) rl:| n3;} n4:} ss:} de:µ js:} mo:? zu:]
                1. Hallo Peter

                  Vielen herzlichen Dank! Ich werde das gleich ausprobieren.

                  Viele Grüsse
                  Stefan

        2. Hi,

          ich bin ja auch nur »interessierter laie«, aber was Cheatah da
             beschreibt, klingt nach "controller"(?) - und jetzt? - das hilft
             Dir keinesfalls weiter, weil Du die konkrete implementierung
             immer noch von hand vornehmen musst.

          klar muss er das, es ging ja nur um das Pattern ;-)

          ich glaube auch, dass Cheatah Dir genau das sagen wollte und
             Dir deshalb den namen listig unterschlagen hat ;-)

          Nein, es ist tatsächlich so, dass ich i.d.R. nicht auf dieser Ebene über Pattern nachdenke. Dass es zu den Objektmodellen und Mechanismen, die ich anfertige, gewöhnlich ein Design Pattern gibt ist mir bewusst - vom Prinzip her kenne ich sie schließlich. Nur halt nicht mit Namen ;-) Den kann ich ohne nachzuschlagen nur sehr selten nennen.

          Cheatah

          --
          X-Self-Code: sh:( fo:} ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
          X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
          X-Will-Answer-Email: No
          X-Please-Search-Archive-First: Absolutely Yes
          1. gruss Cheatah,

            ich bin ja auch nur »interessierter laie«, aber was Cheatah da
               beschreibt, klingt nach "controller"(?) - und jetzt? - das hilft
               Dir keinesfalls weiter, weil Du die konkrete implementierung
               immer noch von hand vornehmen musst.

            klar muss er das, es ging ja nur um das Pattern ;-)

            dann frag' ich mich aber auch, warum der OP den namen
               des entwurfsmusters wissen wollte - dieser (den name)
               ist fuer analyse und loesung des vom OP vorgestellten
               falls ohne bedeutung.

            ratlos - peterS. - pseliger@gmx.net

            --
            »Because objects in JavaScript are so flexible, you will want to think differently about class hierarchies.
            Deep hierarchies are inappropriate. Shallow hierarchies are efficient and expressive.« - Douglas Crockford
            ie:( fl:) br:> va:( ls:& fo:) rl:| n3;} n4:} ss:} de:µ js:} mo:? zu:]
            1. Hallo peterS.,

              dann frag' ich mich aber auch, warum der OP den namen
                 des entwurfsmusters wissen wollte - dieser (den name)
                 ist fuer analyse und loesung des vom OP vorgestellten
                 falls ohne bedeutung.

              Naja, er wusste da gibt es eine "fertige" Lösung. Mit dem Namen hätte er sie nachschlagen und verwenden können.
              Entwurfsmuster sind im Prinzip immer überflüssig, man kann das Problem auch so lösen. Entwurfsmuster haben meiner Meinung nach aber zwei Vorteile:

              • Dokumentation: Wenn man ähnliche Bezeichnungen verwendet, wie bei bestimmten Entwurfsmustern üblich, dann versteht jemand, der das kennt, den Code schneller, weil er sofort die Idee erkennt und nicht erst analysieren muss, wie die Objekte kommunizieren.
              • Anregung für die Lösung: Um OO-Probleme zu lösen, ist es (wie bei fast allen Problemen ;-) hilfreich, über eine Sammlung von Ideen zu verfügen, wie man Probleme lösen kann oder gelöst hat. Man nennt das auch "Erfahrung". Entwurfsmuster vermitteln einem einfach nur ein Stück Erfahrung anderer, man muss das natürlich nicht 1:1 verwenden. Meiner Meinung nach klappt das auch nicht, weil auftretende Probleme zu vielschichtig sind. Von "Mustersprachen" o.ä. wie sie mal in Mode waren (ich habe den Eindruck, dass das nachgelassen hat) halte ich nicht so viel.

              In diesem Fall dürften übrigens die Muster Composite und Decorator relevant sein. Für die Frage, wie man die Panels nun genau an den Controller hängt, helfen die Muster aber auch nicht groß weiter.

              Grüße

              Daniel

              1. Hi,

                Entwurfsmuster sind im Prinzip immer überflüssig, man kann das Problem auch so lösen. Entwurfsmuster haben meiner Meinung nach aber zwei Vorteile:

                ich ergänze um einen dritten: Konzeption. Besonders bei komplexeren Projekten können aufgezeichnete Pattern sehr nützlich sein.

                Cheatah

                --
                X-Self-Code: sh:( fo:} ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
                X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
                X-Will-Answer-Email: No
                X-Please-Search-Archive-First: Absolutely Yes
                1. gruss Daniel, hallo Cheatah,

                  Entwurfsmuster sind im Prinzip immer überflüssig, ...

                  eben nicht.

                  ... haben meiner Meinung nach aber zwei Vorteile:

                  • Dokumentation: ...
                  • Anregung für die Lösung: ...
                    ...
                    Daniel

                  ich ergänze um einen dritten: Konzeption. Besonders bei
                  komplexeren Projekten können aufgezeichnete Pattern sehr
                  nützlich sein.

                  Cheatah

                  ja, danke Euch beiden ...
                     ... mir ist schon klar, was entwurfsmuster sind, was man
                     mit ihnen leisten und was man eben nicht erwarten kann.

                  und gerade weil die praxis nach punkt 3 verlangt, fragte

                  dann frag' ich mich aber auch, warum der OP den namen
                  des entwurfsmusters wissen wollte - dieser (den name)
                  ist fuer analyse und loesung des vom OP vorgestellten

                  ---------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                     ------vvvvv

                  falls ohne bedeutung.

                  ich mich, warum der OP bei einem aus meiner sicht eher
                     trivialen problem das ganz grosse geschuetz auspacken
                     wollte ... ach nee, wollte er ja nicht, er hat nur nach
                     dem namen der waffe gefragt ;-)

                  Naja, er wusste da gibt es eine "fertige" Lösung. Mit dem
                  Namen hätte er sie nachschlagen und verwenden können.

                  ---------------------------------------^^^^^^^^^

                  das bezweifle ich.

                  In diesem Fall dürften übrigens die Muster Composite und
                  Decorator relevant sein. ...

                  mit viel gutem willen, sehe ich da gerade noch so bedarf
                     fuer den "Dekorierer". ich mag abstraktion, und ich bin
                     sehr fuer denkmodelle, die mich beim abstraktionsprozess
                     leiten.
                     aber die *reine lehre* fuer das vom OP gegebene problem
                     durchzuexerzieren finde ich eher theoretisch interessant.
                     aus praktischer sicht (und da denke ich schon an pflege,
                     wartbarkeit, erweiterbarkeit - durchaus auch von dritten)
                     halte ich dies fuer *overkill* ...

                  @Daniel
                            ... so wie Du augenscheinlich ja auch:

                  ... Für die Frage, wie man die Panels nun genau an den
                  Controller hängt, helfen die Muster aber auch nicht
                  groß weiter.

                  warum hacke ich nun so darauf rum? ich bin persoenlich
                     sehr daran interessiert entwurfsprozesse, wie sie bei
                     den *serioesen programmierern* schon lange nicht mehr
                     wegzudenken sind, in teilen auch auf die entwicklung
                     von DOM-scripten/JavaScript-architekturen zu uebertragen.

                  literatur, die zu diesem thema aus breiter praxiserfahrung
                     schoepft, ist leider kaum vorhanden, obwohl ich jede wette
                     eingehe, dass Google seinen anwendungen solche prozesse
                     angedeihen laesst - die »Yahoo! User Interface Library«
                     hat das licht der welt sicher ebenfalls nicht durch
                     *extreme programming* erblickt.

                  betrachten wir z.b. mal folgende basale "Erzeuger"-muster:

                  - der "Prototyp": geil - ein grosser teil sex-appeal des
                       JavaScript-sprachkonzepts fusst auf konstruktoren und
                       eben prototypen.

                  - der "Erbauer": ein praxisrelevanter klassiker - ohne
                       erbauer kein cooles DOM-scripting. warum? weil gerade
                       die schoene neue oberflaechenwelt im hintergrund nach
                       vielschichtiger programmlogik verlangt. ein *builder*
                       parst in meiner idealen welt den DOM-baum, waehlt sub-
                       strukturen entsprechend ihrer css-klassen-namen und
                       fuehrt diese gegebenenfalls weiteren "Erzeuger"n zu.

                  - das "Singleton"-muster ist im JavaScript-kontext wichtig,
                       um z.b. die kapselung eigener komplexer namespaces zu
                       wie auch immer gearteten programmteilen dritter zu
                       gewaehrleisten und kann in seiner wasserfesten umsetzung
                       so aussehen:

                  ~~~javascript var Singleton = new (function () { // new-operator und anonymer konstruktor;

                  //privater kram - z.b. durchaus auch weitere private konstruktor-funktionen.

                  this.constructor = Object; /* verhindert das erzeugen neuer instanzen
                                                     von [[Singleton]], was bis hierhin immer
                                                     noch in dieser art moeglich gewesen waere:

                  var Double = new Singleton.constructor();
                     */

                  //oeffentlicher kram - z.b. eine einzige oeffentliche methode [build] oder [compile]:

                  this.compile = function () {
                         // z.b. die aufgaben eines "Erbauer"s.
                       };
                     })();/* der konstruktor wird unmittelbar nach der initialisierung durch den call-operator
                             ausgefuehrt und weggeschmissen bzw. bei der ausfuehrung intern  ueberschrieben.
                     */

                    
                    
                     mehr faellt mir auf die schnelle nicht ein und wuerde wohl auch  
                     den rahmen sprengen. ich bin aber, wie schon gesagt, sehr daran  
                     interessiert, dieses thema weiter zu eroertern.  
                    
                     by the way:  
                    
                     zarte andeutungen in diese richtung mache ich auch im nachwort  
                     meiner [deutschen uebersetzung](http://www.pseliger.de/translations/Douglas-Crockford/missunderstood-JavaScript.html) von [Douglas Crockfords klassiker](http://javascript.crockford.com/javascript.html)  
                     [»JavaScript: The World's Most Misunderstood Programming Language«](http://javascript.crockford.com/javascript.html).  
                    
                    
                     so long - peterS. - pseliger@gmx.net  
                    
                    
                  
                  -- 
                  »Because objects in JavaScript are so flexible, you will want to think differently about class hierarchies.  
                  Deep hierarchies are inappropriate. Shallow hierarchies are efficient and expressive.« - [Douglas Crockford](http://javascript.crockford.com/)  
                    
                  ie:( fl:) br:> va:( ls:& fo:) rl:| n3;} n4:} ss:} de:µ js:} mo:? zu:]