Chrisi: PHP5 OOP Plugin

Hallo zusammen,

ich möchte in eine Superklasse eine Unterklasse laden und automatisch eine Referenz/Instanz von der Unterklasse in der Superklasse bereit stellen.

So in etwa habe ich mir das zusammengeschustert:

<?  
  
class Superklasse {  
	  
	var $unterklasse;  
	  
	function __construct($unterklasse=NULL){  
		$this->unterklasse = $unterklasse;  
	}  
	  
	function doSomething(){  
		return $this->unterklasse->irgendwas();  
	}  
}  
  
class Unterklasse extends Superklasse {  
	  
	function __construct(){  
		parent::__construct($this);  
	}  
  
	function irgendwas(){  
		return "Hallo Welt";  
	}  
}  
  
?>

Irgendwie komme ich vom Weg ab und finde kein Land, kann mir jemand dabei helfen?

Danke für eure Zeit und Viele
Chrisi

  1. Hi!

    Irgendwie komme ich vom Weg ab und finde kein Land, kann mir jemand dabei helfen?

    Wobei konkret? Ich seh da jetzt erstmal prinzipiell keinen Fehler.

    Lo!

    1. Hallo,

      Wobei konkret? Ich seh da jetzt erstmal prinzipiell keinen Fehler.

      Mein Problem ist das immer nur die Superklasse geladen (instanziert) werden soll. Ich frag mich jetzt wie ich vernünftig eine Instanz von der Unterklasse in die Superklasse bekomme ohne eine direkte Instanz von der Unterklasse zu erstellen.

      Also kurz gesagt, die Superklasse soll automatisch eine Instanz von der Unterklasse erhalten:

      <?  
      $super = new Superklasse();  
      ?>
      

      Viele Grüße.

      1. $this->unterklasse = new Unterklasse() im Konstruktor der Oberklasse? Ist es das, was Du meinst?

        Gruß, Dennis

        1. Hallo Dennis,

          $this->unterklasse = new Unterklasse()

          Jaein, nur soll die Instanz nicht die Superklasse ableiten, sondern die Unterklasse. Ich hab das in meinem 2ten Beispiel gerade nochmal mit einer static var versucht.

          Ich bin mir nicht sicher wie man soetwas richtig macht :)

          Viele Grüße
          Chrisi

      2. Hallo nochmal,

        ich hab noch eine wenig weiter gebaut vllt. versteht man so besser was ich meine:

        <?  
          
        class Superklasse {  
          
                public static $unterklasse;  
          
                function __construct(){  
                        new Unterklasse();  
                }  
          
                function doSomething(){  
                        return self::$unterklasse->irgendwas();  
                }  
        }  
          
        class Unterklasse extends Superklasse {  
          
                function __construct(){  
                        parent::$unterklasse=&$this;  
                }  
          
                function irgendwas(){  
                        return "Hallo Welt";  
                }  
        }  
          
        $superklasse = new Superklasse();  
          
        echo $superklasse->doSomething();  
          
        ?>
        

        Das Beispiel funktioniert soweit, nur frage ich mich ob das so bringen kann oder ob es einen besseren Weg gibt?

        Viele Grüße
        Chrisi

        1. Hi,

          ich hab noch eine wenig weiter gebaut vllt. versteht man so besser was ich meine:

          <?

          class Superklasse {

          public static $unterklasse;

          function __construct(){
                          new Unterklasse();
                  }

          function doSomething(){
                          return self::$unterklasse->irgendwas();
                  }
          }

          class Unterklasse extends Superklasse {

          function __construct(){
                          parent::$unterklasse=&$this;
                  }

          function irgendwas(){
                          return "Hallo Welt";
                  }
          }

          $superklasse = new Superklasse();

          echo $superklasse->doSomething();

          ?>

          
          >   
          > Das Beispiel funktioniert soweit, nur frage ich mich ob das so bringen kann oder ob es einen besseren Weg gibt?  
            
          Erkläre uns doch bitte erst mal, welchen \*Sinn\* das haben soll?  
            
          Wenn du mit den Methoden und Eigenschaften von Unterklasse arbeiten willst - wieso erzeugst du dir dann nicht einfach eine Instanz von Unterklasse und arbeitest damit?  
            
          MfG ChrisB  
            
          
          -- 
          RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
          
          1. Hallo,

            Wenn du mit den Methoden und Eigenschaften von Unterklasse arbeiten willst - wieso erzeugst du dir dann nicht einfach eine Instanz von Unterklasse und arbeitest damit?

            Es geht hierbei um ein Modul für ein CMS. In dem CMS werden die Module in einer Klasse zusammengefasst, die Klasse ist die Superklasse in meinem Beispiel. Das CMS lädt also automatisch eine Instanz von dem Modul bzw. der Superklasse.

            Mein Modul bringt einige Funktionen die ich in keline Plugins (Unterklassen) auslagern will :) Die Funktionen in den Plugins sollen also in dem Modul zur Verfügung stehen.

            Klingt verrückt oder?

            Viele Grüße
            Chrisi

            1. Moin!

              Wenn du mit den Methoden und Eigenschaften von Unterklasse arbeiten willst - wieso erzeugst du dir dann nicht einfach eine Instanz von Unterklasse und arbeitest damit?

              Es geht hierbei um ein Modul für ein CMS. In dem CMS werden die Module in einer Klasse zusammengefasst, die Klasse ist die Superklasse in meinem Beispiel. Das CMS lädt also automatisch eine Instanz von dem Modul bzw. der Superklasse.

              Mein Modul bringt einige Funktionen die ich in keline Plugins (Unterklassen) auslagern will :) Die Funktionen in den Plugins sollen also in dem Modul zur Verfügung stehen.

              Klingt verrückt oder?

              Dein Ansatz ist es jedenfalls, weil er ganz viele Dinge tut, die man zwar tun könnte, aber nicht tun sollte.

              Lass uns erst mal erörtern, was du da eigentlich als Effekt am Ende haben willst.

              class Superklasse {  
                
                      public static $unterklasse;  
                
                      function __construct(){  
                              new Unterklasse();  
                      }  
                
                      function doSomething(){  
                              return self::$unterklasse->irgendwas();  
                      }  
              }  
                
              class Unterklasse extends Superklasse {  
                
                      function __construct(){  
                              parent::$unterklasse=&$this;  
                      }  
                
                      function irgendwas(){  
                              return "Hallo Welt";  
                      }  
              }  
                
              $superklasse = new Superklasse();  
                
              echo $superklasse->doSomething();
              

              Zunächst mal zu dem, was man nicht tun sollte:

              1. Wenn deine Unterklasse in die Superklasse individuelle Funktionalität einbringen soll, dann ist das hier total überflüssig: Unterklasse extends Superklasse. Warum Vererbung?

              Ich meine: WENN Vererbung, dann richtig, indem du zur Nutzung nur die Unterklasse instantiierst, und sich damit dein Problem erledigt.

              2. Das Erstellen einer explizit benannten Unterklasse im Konstruktor ist ebenfalls nicht schön. Das, was du eigentlich an der Stelle tun willst, was sich in deiner ersten Codeversion auch dargestellt hat, ist das Übergeben der Unterklasse als Parameter im Konstruktor. Sowas nennt man Dependency Injection, und deine gewählte Variante ist davon die einfachste.

              Jetzt hast du als Anforderung aber erwähnt, dass es blöd ist, wenn die Superklasse immer noch eine Instanz der Unterklasse mitbekommen muss. Für sowas schreibt man sich dann eine Factory, die die einzelnen Objekte für einen zusammensetzt. Vorteil: Das Instanziieren einer Superklasse integriert halt nicht automatisch immer dieselbe Unterklasse - denn wo wäre da der Vorteil, da kann man die darin befindlichen Methoden ja gleich in der Superklasse integrieren.

              Aber um zu wissen, was genau du da jetzt eigentlich tun willst, solltest du noch mehr Details preisgeben, was da eigentlich genau getan werden soll von deinen ganzen Klassen. Es gibt noch deutlich mehr Entwicklungsmuster, die für "irgendwas mit Plugin drin" in Frage kommen, aber mir fehlt halt die Info, wozu du das eigentlich so kompliziert aufziehst.

              - Sven Rautenberg

              1. Hallo Sven & alle anderen,

                vorweg danke für eure Antworten :)

                Für sowas schreibt man sich dann eine Factory

                Ich denke eine factory ist genau das was ich gesucht habe :) Ich habe die Unterklasse jetzt von der Erweiterung "extends" befreit und mir eine Factory Methode in die Superklasse gebaut dir mir meine gewünschte Unterklasse als Referenz holt.

                Einziges Problem, wenn ich wie vorgeschlagen die Vererbung "extends" in der Unterklasse weglasse fehlen mir die Funktionen+Variablen von der Superklasse in der Unterklasse.

                Zusammengefasst, möglich sein soll:

                1. Eine Erweiterung der Funktionalität der Superklasse durch dynamisches nachladen von Instanzen (factory).

                2. Zugriff auf alle Funktionen und Variablen der Superklasse innerhalb der Unterklasse bzw. der Instanz der Unterklasse.

                In der Unterklasse werden z.B: Formulare gebaut die jeweils und nur für das eine Plugin welches aus der Unterklasse entsteht gültig sind.

                Jetzt ist die Frage wie ich alles was in der Superklasse steckt vernünftig in die Unterklasse bekomme ohne extends (oder vllt. doch mit) zu nutzen?

                Ich glaube es geht in die richtige Richtigung, mir fehlt jedoch die Erfahrung mit den versch. Mustern.

                Viele Grüße
                Chrisi

                1. Hallo nocheinmal,

                  Jetzt ist die Frage wie ich alles was in der Superklasse steckt vernünftig in die Unterklasse bekomme ohne extends (oder vllt. doch mit) zu nutzen?

                  Ich glaube hier habe ich einen Weg gefunden der mir als gut erscheint :)

                  In meiner factory habe ich einen optionalen Paramater eingebaut mit dem ich eine Referenz auf die Superklasse lege die ich im __construct der Unterklasse annehme.

                  Somit habe ich aus allen meinen Unterklassen die Verbung "extends" entfernt und kann bei Bedarf auf alle Funktionen der Superklasse innerhalb der Unterklasse ($this->super->...) zugreifen.

                  Jetzt bleibt nur die Frage ob das aus Programmierer Sicht eine gute Lösung ist? Und wenn ja ob dieses Muster einen speziellen Namen hat? (Oder bleibt es eine factory?)

                  Danke und Viele Grüße
                  Chrisi

                  1. Tach auch.

                    Somit habe ich aus allen meinen Unterklassen die Verbung "extends" entfernt und kann bei Bedarf auf alle Funktionen der Superklasse innerhalb der Unterklasse ($this->super->...) zugreifen.

                    Ich verstehe deinen Ansatz nicht, bzw. du lieferst zuwenig Informationen über dein Problem.

                    Zunächst einmal: die Vaterklasse von einer Kindklasse so abhängig zu machen, halte ich für merkwürdig. Wenn die Vaterklasse ohne Kindklasse nicht funktioniert, ist es entweder eine Klasse oder die Vaterklasse ist abstrakt.

                    Der Ansatz, der mir bei sowas einfiele, wäre folgender:
                    Die Vaterklasse wird abstrakt. Alle Methoden, die direkt von den Kindklassen abhängig sind (aus deinem jetzigen Modell) werden abstrakt und werden dann in den Kindklassen implementiert. Etwaiger gemeinsamer Code kann durch protected-Methoden in der Vaterklasse  bereitgestellt werden.
                    Instantiiert werden also nur Kindklassen.
                    Das Factory-Pattern kannst du nun einsetzen, um aus einer statischen Methode der Vaterklasse abhängig von Parametern das richtige Kindobjekt zu erzeugen und zurückzugeben.

                    Bis die Tage,
                    Matti

                    1. Hallo,

                      Die Vaterklasse wird abstrakt.

                      Wenn ich die Vaterklasse als abstract deklariere kann ich keine direkte Instantz mehr von dieser erzeugen, diese wird aber benötigt.

                      Mein Problem ist das es sich bei meiner Superklasse nur um ein Modul für eine darunterligende Applikation handelt. Dieses Modul ist nicht abstract und wird selber schon instanziert soll aber mit kleinen Plugins funktionieren um wiederkehrende Funktionen dynamisch nachladen zu können.

                      Viele Grüße
                      Chrisi

  2. Hey Chrisi,

    Irgendwie komme ich vom Weg ab und finde kein Land, kann mir jemand dabei helfen?

    und wo ist Dein Problem? Außer, dass das nicht direkt was mit "OOP Plugin" zu tun hat (da ich nciht weiß, was das heißt), sieht das obige für mich richtig aus.

    Gruß, Dennis