web-dev-qa-db-de.com

Erstellen Sie eine Klasseninstanz aus der statischen Methode

Wie der Titel sagt, möchte ich eine Instanz einer Klasse aus einer statischen Methode derselben Klasse erstellen. Ich habe bisher herausgefunden, dass ich dies tun kann:

class Foo{

 public $val;

 public static function bar($val){
  $inst = new Foo;
  $inst->val = $val;
  return $inst;
 }

}

Was mich deshalb tun lässt.

$obj = Foo::bar("some variable");

Was großartig ist.

So jetzt die Fragen. Gibt es einen einfacheren Weg, den ich nicht kenne, oder irgendwelche Abkürzungen, um dasselbe Ergebnis zu erzielen? Gibt es Vor- oder Nachteile, eine Instanz auf diese Weise zu erstellen?

Vielen Dank.

32
daniel

Sie tun das so, wie Sie es tun. Es gibt ein paar andere Dinge, die Ihnen das Leben erleichtern können und die Sie auch tun können.

  1. Den Klassennamen nicht hartcodieren. Wenn Sie 5.3 oder höher verwenden, verwenden Sie das Schlüsselwort static . Auf diese Weise kann die neue Funktion, wenn Sie die Klasse erweitern, auch diese instanziieren:

    public static function bar($var) {
        $obj = new static();
        $obj->var = $var;
        return $obj;
    }
    

    Dann können Sie es in jeder Erweiterungsklasse verwenden, ohne etwas überschreiben zu müssen.

  2. Stellen Sie fest, ob $var durch einen Konstruktor übergeben werden sollte, anstatt nach der Konstruktion festgelegt zu werden. Wenn das Objekt davon abhängt, sollten Sie es anfordern.

    public function __construct($var) {
        $this->var = $var;
    }
    

    Auf diese Weise können Sie das Objekt nicht instanziieren, ohne die Variable festzulegen.

  3. Erzwingen Sie die Instantiierung der Klasse durch die statische Methode. Wenn Sie dort etwas tun, was Sie tun müssen, dann machen Sie den Konstruktor entweder geschützt oder privat. Auf diese Weise kann niemand die statische Methode umgehen.

    protected function __construct() {}
    private function __construct() {}
    

Ich hoffe das hilft...

Edit: Basierend auf Ihrem Kommentar oben klingt es für mich wie Sie versuchen, das Singleton Design Pattern zu implementieren. Es gibt unzählige Informationen darüber, warum es keine gute Idee ist und welche schlechten Dinge es tun kann. Es hat auch Verwendung. 

Es gibt jedoch einige andere Muster, die für Sie von Nutzen sein können, je nachdem, was Sie genau tun.

  • Sie können Factory-Methode verwenden, wenn Sie versuchen, verschiedene Objekte mit den gleichen Schritten zu erstellen.
  • Wenn alle Objekte gleich beginnen und dann angepasst werden, können Sie das Prototypmuster verwenden.
  • Sie könnten einen Object Pool verwenden, wenn das Erstellen eines Objekts besonders teuer ist.

Zu beachten ist jedoch, dass Objekte in PHP ziemlich leicht sind. Versuchen Sie nicht, ein neues Objekt nur für diesen Aufwand zu erstellen. Vermeiden Sie mehrmals, schwere Dinge wie Datenbankabfragen oder Dateisystemzugriffe durchzuführen. Aber machen Sie sich keine Sorgen über den Aufruf von new Foo(), es sei denn, der Konstruktor von foo ist besonders schwer ...

78
ircmaxell

Das sieht aus wie ein einfaches Factory-Pattern.

Sie haben einen netten Vorteil: Nehmen Sie an, Sie möchten in Zukunft eine andere Implementierung verwenden (die aber dasselbe tut). Mit einer Factory können Sie alle Objekte ändern, die an vielen Stellen eines komplexen Systems erstellt werden, indem Sie einfach die Erstellermethode ändern. Beachten Sie, dass dies einfacher wäre, wenn Sie eine externe Klasse verwenden (wie im ersten Link unten).

Wenn Sie es so beibehalten, wie Sie es jetzt haben, können Sie diese Klasse auch subklassen und die Methode überschreiben, um ein komplexeres Objekt zu erstellen. Ich glaube nicht, dass Sie das hier erreichen wollen.

Dies ist auf jeden Fall gut, um Test Driven Development, Abstraktion und viele andere gute Dinge zu ermöglichen.

links:

  1. PHP Muster
  2. Factory Method Pattern auf Wikipedia
3
Pedro Loureiro

Wenn Sie nur ein Objekt erstellen, ist dies nicht sehr nützlich. Sie könnten einfach einen Konstruktor aufrufen. Wenn Sie jedoch etwas komplizierter machen (wenn Sie mit einem Singleton-Pattern beginnen, aber nicht alle Details in diesem Beispiel enthalten haben), dann:

Das klingt ungefähr richtig. Wenn Sie verhindern möchten, dass Objekte standardmäßig wie folgt erstellt werden:

$obj = new Foo("Some Variable");

Sie können einen privaten Konstruktor hinzufügen:

class Foo{

 public $val;

 private __construct(){}

 public static function bar($val){
  $inst = new Foo;
  $inst->val = $val;
  return $inst;
 }
}

Jetzt erzwingen Sie Leute, um Ihre statische Klasse zu verwenden. Die Notwendigkeit, den Wert in der Funktion festzulegen, ist möglicherweise nicht mehr vorhanden. Sie können also den Wert-Parameter zu Ihrem privaten Konstruktor hinzufügen, aber die anderen Dinge (die Sie vermutlich tun möchten, z. B. nach einem Singleton-Muster suchen) in Ihrem Bar-Funktion

0
Nanne