Ankündigung

Einklappen
Keine Ankündigung bisher.

Design Pattern: Klasse mehrfach um einzelne Funktionalitäten erweitern

Einklappen

Neue Werbung 2019

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

  • Design Pattern: Klasse mehrfach um einzelne Funktionalitäten erweitern

    Hi,

    ich möchte eine Klasse mehrfach um Funktionalität erweitern, konkret den ViewHelper HeadLink von Zend.

    Für alle die das ZF nicht kennen: HeadLink repräsentiert eine Sammlung von <link />-Tags des Headers.

    Meine Funktionalitäten sollen sein:
    Merge
    Minify
    Cache

    Merge soll mehrere <link />-Tags zu einem zusammenfassen.

    Minify soll die Datei eben klein machen, also Whitespaces entfernen.

    Cache soll das Ergebnis von allem cachen.

    Wie nennt sich denn das Entwurfmuster um HeadLink um Funktionalität zu erweitern? Decorator, ist es ein Proxy, keines von beidem?

    Den Code stelle ich mir in etwa so vor:

    PHP-Code:
    <?php
    class Zend_View_Helper_HeadCommon extends Zend_View_Helper_Abstract {
      public function 
    toString($indent 8)
      {
        
    $headLink = new Zend_View_Helper_HeadLink_Decorator_Base($this->view->headLink);
        if (
    $this->_mergeCss) {
          
    $headLink = new Zend_View_Helper_HeadLink_Decorator_Merge($headLink);
        }
        if (
    $this->_minifyCss) {
          
    $headLink = new Zend_View_Helper_HeadLink_Decorator_Minify($headLink);
        }
        if (
    $this->_cacheCss) {
          
    $headLink = new Zend_View_Helper_HeadLink_Decorator_Cache($headLink);
        }
        return 
    $headLink->toString($indent);
      }
    }
    ?>
    (statt new vermutlich eher $this->view->headDecorator($headLink), aber ist nur zur Veranschaulichung).

    Als Schnittstelle schwebt mir so etwas vor:
    PHP-Code:
    <?php
    interface Zend_View_Helper_HeadLink_Decorator_Interface
    {
      public function 
    getHeadLinkModificationId();
      public function 
    toString($indent null);
    }
    ?>
    So könnte das Caching auch wirklich greifen, nämlich in dem Merge und Minify nur eine Quersumme aus Dateinamen und Änderungsdatum für getModificationId() zurückliefern.

    Vorgehensweise gut?
    Wie heißt das Pattern?

    Zumindest bei Zend_Form_Decorator wird es ja ähnlich gemacht, wenn auch iterativ statt verschachtelt.

  • #2
    Hmm, präzise evtl. keines von beidem. Adapter w.ürde ich sagen. Oder benutzt Dein Objekt ein gemeinsames Interface mit HeadLink? (kann man hieraus nicht ersehen)

    Ich würde hier vermutlich Proxy bevorzugen. Ich kenne Zend nicht so gut, aber kriegst Du die Belange denn so weit getrennt, dass Dekorieren überhaupt möglich ist?
    Auf der Kehrseite sparst Du ne Menge Klassen und solange Du sowieso alles innerhalb eines Objektes erzeugst, kannst Du die Vorteile von Dekoratoren ja kaum ausspielen.

    Kommentar


    • #3
      Zitat von nikosch Beitrag anzeigen
      Hmm, präzise evtl. keines von beidem. Adapter w.ürde ich sagen. Oder benutzt Dein Objekt ein gemeinsames Interface mit HeadLink? (kann man hieraus nicht ersehen)
      Nein, die benutzen ein eigenes, daher dachte ich mir, dass ich die Basic-Klasse noch benutze, um den nachfolgenden ein gemeinsames Interface zu bieten.

      Zitat von nikosch Beitrag anzeigen
      Ich würde hier vermutlich Proxy bevorzugen. Ich kenne Zend nicht so gut, aber kriegst Du die Belange denn so weit getrennt, dass Dekorieren überhaupt möglich ist?
      Auf der Kehrseite sparst Du ne Menge Klassen und solange Du sowieso alles innerhalb eines Objektes erzeugst, kannst Du die Vorteile von Dekoratoren ja kaum ausspielen.
      Ja, ich habe mir jetzt mal Minify angesehen, das macht mergen, minifien und cachen wohl in einem.
      Hätte sich dann auch erübrigt.

      Zum Adapter: Ich dachte das wäre nur die Anpassung einer Klasse an eine feste Schnittstelle, der Hauptfokus bei mir ist ja aber vielmehr die Funktionalitätserweiterung. Wobei die Übergänge bei manchen Patterns ja fließend sind.

      Evtl. hat sich mit Minify sowieso schon alles erledigt.

      Kommentar


      • #4
        Zum Adapter: Ich dachte das wäre nur die Anpassung einer Klasse an eine feste Schnittstelle, der Hauptfokus bei mir ist ja aber vielmehr die Funktionalitätserweiterung.
        Naja, stimmt auch wieder

        Kommentar


        • #5
          Das was du da vor hast sind doch einfach Filter. Die kann man einfach in einen Stack hinzufügen und bei der Ausgabe wird nach einander durch-gefiltert.

          Bieten die Container von Zend_View_Helper_* nicht an, aber sollte einfach sein headLink() entsprechend zu erweitern.

          P.S. der bessere Weg wäre es das beim Deployment zu verkleinern.

          Kommentar


          • #6
            Nach dem Einwurf verstehe ich das erstmal.
            Merge soll mehrere <link />-Tags zu einem zusammenfassen.
            bedeutet, Du willst die Ressourcen darin mergen und minifizieren?! Ach sohoho.

            Kommentar


            • #7
              Oh man diese Zend Klassennamen also in Kohana nutze ich das Module Asset-Merger

              Dieser Merger macht Minify und Merge mit bereits bestehenden Bibliotheken, Das Caching übernimmt das Kohana Cache Modul. Eventuell hilft dir der Quellcode als Idee

              MFG

              Kommentar


              • #8
                @BlackScorp:
                LOL ok die Klassennamen sind echt etwas lang, wie gesagt, mit $this->view->headDecorator() wärs etwas kürzer

                @nikosch:
                genau, beides

                @lcrash:
                Filter klingt tatsächlich sinnvoll. Das soetwas ins Deployment gehört stimmt irgendwie, nur deploy ich bei PHP so selten "richtig". Da mach ich halt ein SVN up auf die stable-Version und gut ist. Wie machst du das denn?

                Kommentar


                • #9
                  Zitat von Chriz Beitrag anzeigen
                  @BlackScorp:
                  LOL ok die Klassennamen sind echt etwas lang, wie gesagt, mit $this->view->headDecorator() wärs etwas kürzer
                  in kohana haben die das so gelöst dass sie ein classes ordner haben in dem leere klassen drin sind

                  PHP-Code:
                  class HeadCommon extends Zend_View_Helper_HeadCommon{} 
                  somit bruachste dann halt nur HeadCommon aufzurufen, zusätzlicher vorteil ist noch, dass du dann die klassen mit eigenen methoden erweitern kannst, oder vorhandene methoden überschreiben kannst ohne dabei die core klassen anfassen zu müssen. aber gibt es denn keinen Zend Modul um JS/CSS dateien zu "minfieren"? wieso Programmierst du es selber?

                  Kommentar


                  • #10
                    Wie machst du das denn?
                    Würde mich auch interessieren.
                    Oh man diese Zend Klassennamen
                    Liegt vermutlich am Autoloader-Prinzip, was? Obwohl ich gestehen muss, meine Bezeichner sind oftmals auch sehr lang. Obwohl ich per Konfiguration registriere. Aber präzise Namen finde ich wichtig. Zumindest, bis Namespaces überall verfügbar sind.

                    Kommentar


                    • #11
                      Das Deployment soll demnächst über Phing laufen. Vorarbeiten dafür sind schon gemacht.

                      Warum sich die Leute über die langen Klassennamen aufregen? Wir nutzen PHP 5.3 Namespaces und somit war die Umstellung leichter, kürzen wurden diese dabei allerdings nicht (nur bei mehrfach verwendetem).

                      In ZF 2.0 wird sich das ganze im übrigen so lösen lassen, dass du ein Event an den View-Helper anhängst und dann beim feuern filterst.

                      Kommentar

                      Lädt...
                      X