Créer une instance de classe à partir d'une méthode statique

Comme le titre l'indique, je souhaite créer une instance d'une classe à partir d'une méthode statique de la même classe. J'ai compris jusqu'à présent que je peux en faisant quelque chose comme ceci:

class Foo{

 public $val;

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

}

Ce Qui me permet donc de le faire.

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

Ce qui est génial.

Alors maintenant les questions. Y a-t-il un moyen plus facile de le faire que je ne connais pas, ou des raccourcis pour atteindre le même résultat? Y a-t-il des avantages ou des inconvénients à créer une instance dans ce de la mode?

Merci.

28
demandé sur daniel 2011-01-11 17:16:51

3 réponses

Ils façon dont vous le faites est très bien. Il y a quelques autres choses qui peuvent vous rendre la vie plus facile que vous pouvez faire aussi bien.

  1. Ne codez pas en dur le nom de la classe. Si vous êtes sur 5.3+, utilisez le mot-clé static. De cette façon, si vous étendez la classe, la nouvelle fonction peut également instancier celle-ci:

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

    Ensuite, vous pouvez l'utiliser dans n'importe quelle classe d'extension sans avoir besoin de remplacer quoi que ce soit.

  2. Déterminez si $var doit être transmis par un constructeur plutôt que de définir après la construction. Si l'objet en dépend, vous devriez l'exiger.

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

    De cette façon, vous ne pouvez pas instancier l'objet sans définir la variable.

  3. Appliquer l'instanciation de la classe via la méthode statique. Si vous faites quelque chose là-dedans que vous devez faire, alors faites le constructeur soit protégé ou privé. De cette façon, quelqu'un ne peut pas contourner la méthode statique.

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

J'espère que aider...

Edit: sur la base de votre commentaire ci-dessus, il me semble que vous essayez d'implémenter le modèle de conception Singleton. Il y a des tonnes d'informations sur la raison pour laquelle ce n'est pas une bonne idée et les mauvaises choses qu'elle peut faire. Il a des utilisations aussi bien.

, Mais il existe d'autres modèles qui peuvent vous être utiles, en fonction de ce que vous faites exactement.

  • vous pouvez utiliser la méthode D'usine Si vous essayez de créer objets utilisant les mêmes étapes.
  • si tous les objets commencent de la même manière et sont ensuite personnalisés, vous pouvez utiliser le modèle Prototype .
  • vous pouvez utiliser un Pool D'objets s'il est particulièrement coûteux de créer votre objet.

Mais une chose à considérer, c'est qu'en PHP les objets sont assez légers. N'essayez pas d'éviter de créer un nouvel objet juste pour cette surcharge. Évitez de faire des choses lourdes comme les requêtes de base de données ou les accès au système de fichiers à de multiples reprises. Mais ne vous inquiétez pas d'appeler new Foo() à moins que le constructeur de foo ne soit particulièrement lourd...

73
répondu ircmaxell 2011-01-11 14:41:37

Cela ressemble à un modèle de méthode d'usine simple.

Vous avez un bel avantage: supposons qu'à l'avenir vous vouliez commencer à utiliser une implémentation différente (mais cela fait la même chose). En utilisant une usine, vous pouvez modifier tous les objets créés dans de nombreux endroits d'un système complexe simplement en changeant la méthode creator. Notez que cela fonctionnerait plus facilement si vous utilisiez une classe externe (comme dans le premier lien ci-dessous).

En le gardant comme vous l'avez maintenant, vous pouvez également sous-classer cette classe et remplacer la méthode pour créer un objet plus complexe. Je ne pense pas que ce soit ce que vous voulez réaliser ici.

Quoi qu'il en soit, c'est bon pour permettre le développement piloté par les tests, l'abstraction et beaucoup d'autres bonnes choses.

Liens:

  1. modèles Php
  2. modèle de méthode D'usine sur wikipedia
3
répondu Pedro Loureiro 2011-01-11 14:36:27

Si vous créez simplement un objet, ce n'est pas très utile. Vous pouvez simplement appeler un constructeur. Mais si vous faites quelque chose de plus compliqué (comme si vous commencez avec une sorte de modèle singleton mais n'avez pas inclus tous les détails dans cet exemple), alors:

Cela semble à peu près juste. Si vous voulez empêcher les objets créés de la manière par défaut comme ceci:

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

Vous pouvez ajouter un constructeur privé:

class Foo{

 public $val;

 private __construct(){}

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

Maintenant, vous obligez les gens à utiliser votre classe statique. Le besoin de définir le val dans la fonction peut être parti, donc vous pouvez même ajouter le paramètre value à votre constructeur privé mais faire les autres choses (que vous voulez probablement faire, comme vérifier une sorte de modèle singleton) dans votre fonction 'bar'

0
répondu Nanne 2011-01-11 14:28:07