web-dev-qa-db-fra.com

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. Jusqu'ici, j'ai compris que je pouvais faire 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 faire cela.

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

Qui est genial.

Alors maintenant, les questions. Y a-t-il un moyen plus facile de faire cela dont je ne suis pas au courant, ou des raccourcis pour atteindre le même résultat? Y at-il des avantages ou des inconvénients à créer une instance de cette manière?

Merci.

32
daniel

Ils font comme vous le faites, c'est bien. Il existe quelques autres choses qui peuvent vous rendre la vie plus facile.

  1. Ne codez pas en dur le nom de la classe. Si vous êtes sous 5.3+, utilisez le mot-clé static . Ainsi, 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 extensible sans rien modifier.

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

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

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

  3. Appliquez l'instanciation de la classe via la méthode statique. Si vous faites quelque chose que vous devez faire, faites en sorte que 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 ça aide ...

Edit: D'après votre commentaire ci-dessus, il me semble que vous essayez d'implémenter le Singleton Design Pattern . Il existe des tonnes d'informations sur les raisons pour lesquelles ce n'est pas une bonne idée et les mauvaises choses que cela peut faire. Il a aussi des utilisations. 

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

  • Vous pouvez utiliser Méthode d'usine si vous essayez de créer différents objets en suivant les mêmes étapes.
  • Si tous les objets démarrent de la même façon, puis sont personnalisés, vous pouvez utiliser le motif Prototype Pattern .
  • Vous pouvez utiliser un Object Pool s'il est particulièrement coûteux de créer votre objet.

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

78
ircmaxell

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

Vous avez un avantage gentil: supposez qu'à l'avenir, vous souhaitiez utiliser une implémentation différente (mais cela revient au même). À l'aide d'une fabrique, vous pouvez modifier tous les objets créés à de nombreux endroits d'un système complexe en modifiant simplement 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 tel que vous l'avez maintenant, vous pouvez également sous-classer cette classe et redéfinir 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 bien pour permettre le développement piloté par les tests, l’abstraction et bien d’autres bonnes choses.

liens:

  1. Modèles Php
  2. Modèle de méthode d'usine sur wikipedia
3
Pedro Loureiro

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 commenciez avec une sorte de modèle de singleton sans inclure tous les détails dans cet exemple), alors:

Cela sonne juste. Si vous voulez empêcher les objets créés par défaut, procédez comme suit:

$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. La nécessité de définir la valeur de la fonction a peut-être disparu, vous pouvez même ajouter le paramètre value à votre constructeur privé, mais vous pouvez également effectuer les autres opérations fonction 'bar'

0
Nanne