Quand utiliser statique vs instancié classes
PHP, c'est mon premier langage de programmation. Je n'arrive pas à envelopper ma tête autour de quand utiliser les classes statiques vs objets instanciés.
Je me rends compte que vous pouvez copier et dupliquer des objets. Cependant, dans tous de mon temps à l'aide de php n'importe quel objet ou la fonction termine toujours comme une seule déclaration (array, string, int) valeur ou nuls.
Je comprends les concepts dans des livres comme un personnage de jeu vidéo de la classe. double objet voiture et de faire le nouveau rouge, que tout fait sens, mais ce n'est pas son application en php et web applications.
Un exemple simple. Un blog. Quels sont les objets d'un blog serait le mieux mis en œuvre comme statique ou objets instanciés? La classe DB? Pourquoi ne pas simplement créer une instance de la db objet dans la portée globale? Pourquoi ne pas faire de chaque objet statique à la place? Quid des performances?
Est tout simplement le style? Est-il une bonne façon de faire ce genre de choses?
Vous devez vous connecter pour publier un commentaire.
C'est assez intéressante question, et les réponses peuvent être intéressant aussi ^^
La façon la plus simple de penser à des choses peut-être :
(Ouais, j'avoue, vraiment, vraiment trop simplifié...)
Une chose à propos des méthodes statiques/classes, c'est qu'ils ne facilitent pas les tests unitaires (au moins en PHP, mais probablement dans d'autres langues).
Une autre chose à propos de la statique des données est d'une seule instance, il en existe un dans votre programme : si vous définissez Maclasse::$myData une valeur à quelque part, il va avoir cette valeur, et seulement, à chaque où, Parlant de l'utilisateur, vous serez en mesure d'avoir un seul utilisateur -- qui n'est pas très grande, est-il ?
Pour un système de blog, que pouvais-je dire ? Il n'y a pas beaucoup que je voudrais écrire comme statique, en fait, je pense que, peut-être que le DB-classe d'accès, mais probablement pas, en fin de compte ^^
Les deux raisons principales contre l'utilisation de méthodes statiques sont:
Avoir une statique de l'appel de méthode à l'intérieur d'une autre méthode est en fait pire que l'importation d'une variable globale. En PHP, les classes sont des symboles globaux, de sorte que chaque fois que vous appelez une méthode statique, vous misez sur un symbole mondial (le nom de la classe). C'est le cas lorsqu'elle est mal. J'ai eu des problèmes avec ce genre d'approche avec certains composants de Zend Framework. Il y a des classes qui utilisent des méthodes statiques (usines) afin de construire des objets. Il m'était impossible d'en fournir une autre usine à cette instance afin d'obtenir une personnalisation de l'objet renvoyé. La solution à ce problème est de n'utiliser que des instances et instace méthodes et de faire respecter les singletons et la comme dans le début du programme.
Miško Hevery, qui travaille comme Coach Agile chez Google, a une théorie intéressante, ou plutôt à conseiller, que l'on doit séparer la création de l'objet temps de le temps de nous utiliser l'objet. Ainsi, le cycle de vie d'un programme est divisé en deux. La première partie (la
main()
méthode disons), qui prend soin de tout le câblage d'objets dans votre application et la partie qui fait tout le boulot.Alors au lieu d'avoir:
Nous devrions plutôt faire:
Et puis, dans l'index ou la page principale, nous aimerions le faire (c'est l'objet de câblage étape, ou le temps de créer le graphe d'instances pour être utilisé par le programme):
L'idée principale est de découpler les dépendances de vos classes. De cette façon, le code est beaucoup plus extensible et, la partie la plus importante pour moi, testable. Pourquoi est-il plus important d'être testable? Parce que je n'ai pas toujours écrire le code de bibliothèque, de sorte que l'extensibilité n'est pas si important que cela, mais la testabilité est important quand je fais le refactoring. De toute façon, testable code produit généralement extensible code, donc c'est pas vraiment une question de choix ou d'une situation.
Miško Hevery fait également une distinction claire entre les singletons et les Singletons (avec ou sans un S majuscule). La différence est très simple. Les Singletons avec une minuscule "s" sont appliquées par le câblage dans l'index principal. Vous instanciez un objet d'une classe qui ne pas implémenter le pattern Singleton et de prendre soin que vous ne passer qu'une instance à une autre instance qui en a besoin. D'autre part, Singleton, avec un grand "S" est une mise en œuvre de la classique (anti-)modèle. Fondamentalement, un mondial dans le déguisement qui ne ont pas beaucoup d'utilisation en PHP. Je n'en ai pas vu jusqu'à ce point. Si vous ne voulez qu'une seule connexion DB pour être utilisé par tous vos classes est mieux de le faire comme ceci:
En procédant comme ci-dessus, il est clair que nous avons un singleton et nous avons aussi un bon moyen pour injecter une maquette ou d'un tampon dans nos tests. C'est surprenant comment les tests unitaires conduire à une meilleure conception. Mais il fait beaucoup de sens quand vous pensez à ce que les tests de vous forcer à réfléchir sur la façon dont vous devriez utiliser ce code.
La seule situation où j'avais utiliser (et je l'ai utilisé pour imiter le JavaScript prototype d'objet en PHP 5.3) les membres statiques, c'est quand je sais que le champ concerné aura la même valeur de la croix-exemple. À ce stade, vous pouvez utiliser une propriété statique et peut-être une paire de la statique des getter/setter. De toute façon, n'oubliez pas d'ajouter la possibilité pour remplacer le membre statique avec un membre de l'instance. Par exemple Zend Framework a l'aide d'une propriété statique afin de spécifier le nom de l'adaptateur DB classe utilisée dans les cas de
Zend_Db_Table
. Il a été un certain temps depuis que j'ai utilisé de sorte qu'il peut ne plus être pertinente, mais c'est la façon dont je m'en souviens.Méthodes statiques qui ne traitent pas les propriétés statiques doivent être des fonctions. PHP dispose de fonctions et nous devons les utiliser.
Donc en PHP statique peut être appliqué à des fonctions ou des variables. Non les variables statiques sont liés à une instance spécifique d'une classe. Non statique méthodes de loi sur l'instance d'une classe. Donc, nous allons faire une classe appelée
BlogPost
.title
serait un non-membre statique. Il contient le titre de ce billet de blog. On pourrait également avoir une méthode appeléefind_related()
. Il n'est pas statique, car il a besoin d'informations à partir d'une instance spécifique de l'article du blog de la classe.Cette classe devrait ressembler à quelque chose comme ceci:
Sur l'autre main, à l'aide des fonctions statiques, vous pouvez écrire une classe comme ceci:
Dans ce cas, puisque la fonction est statique et n'agit pas sur tout billet de blog particulier, vous devez passer le blog en tant qu'argument.
Fondamentalement c'est une question à propos de la conception orientée objet. Vos cours sont les noms dans votre système et les fonctions qui agissent sur eux sont les verbes. Les fonctions statiques sont d'ordre procédural. Vous passez à l'objet de l'fonctions comme arguments.
Mise à jour: je voudrais aussi ajouter que la décision est rarement entre les méthodes d'instance et des méthodes statiques, et de plus en plus entre l'utilisation des classes et à l'aide de tableaux associatifs. Par exemple, dans une application de blogs, soit vous lisez les messages de blog à partir de la base de données et de les convertir en objets, ou de vous laisser dans le jeu de résultats et de les traiter comme des tableaux associatifs. Ensuite, vous écrivez des fonctions qui prennent des tableaux ou des listes de tableaux associatifs comme arguments.
Dans le OO scénario, vous méthodes d'écriture sur votre
BlogPost
classe qui agissent sur les postes individuels, et vous écrivez les méthodes statiques de la loi sur les collections de postes.Un long chemin, oui. Vous pouvez écrire parfaitement bons programmes orientés objets, sans jamais utiliser de membres statiques. En fait, certaines personnes diront que les membres statiques sont une impureté dans la première place. Je dirais que - en tant que débutant en poo - vous essayer d'éviter de membres statiques tous ensemble. Il va vous forcer dans le sens de l'écriture dans un orientée objet plutôt que de procédure style.
J'ai une approche différente de la plupart des réponses ici, en particulier lors de l'utilisation de PHP. Je pense que toutes les classes doivent être statique, sauf si vous avez une bonne raison, pourquoi pas. Une partie de la "pourquoi pas" les raisons sont les suivantes:
Permettez-moi de prendre un exemple. Étant donné que chaque script PHP génère du code HTML, mon cadre est un html écrivain de classe. Cela garantit qu'aucune autre classe va tenter d'écrire le code HTML car il est spécialisé tâche qui devrait être concentrée dans une seule classe.
En général, vous utilisez le code html de la classe comme ceci:
Chaque fois get_buffer() est appelée, elle réinitialise tout, de sorte que la prochaine classe à utiliser le html écrivain commence dans un état connu.
Toutes mes classes statiques ont une fonction init() qui doit être appelée avant que la classe est utilisée pour la première fois. C'est plus par convention que d'une nécessité.
L'alternative à une classe statique dans ce cas est en désordre. Vous ne voudriez pas que chaque classe qui a besoin d'écrire un petit peu de html d'avoir à gérer une instance de l'html écrivain.
Maintenant, je vais vous donner un exemple de quand ne pas utiliser les classes statiques. Ma classe de formulaire gère une liste de la forme des éléments, comme des saisies de texte, listes déroulantes et plus. Il est généralement utilisé comme ceci:
Il n'y a aucun moyen que vous pouvez le faire avec les classes statiques, d'autant plus que certains des constructeurs de chaque classe de faire beaucoup de travail. Aussi, la chaîne de la succession pour tous les éléments est assez complexe. Donc, c'est un exemple clair où les classes statiques ne doivent pas être utilisés.
La plupart des classes utilitaires tels que ceux de la conversion/chaînes de mise en forme sont de bons candidats pour être une classe statique. Ma règle est simple: tout se passe statique en PHP sauf si il y a une raison pourquoi il ne devrait pas.
"Avoir une statique de l'appel de méthode à l'intérieur d'une autre méthode est en fait pire que l'importation d'une variable globale." (définir le "pire")... et les "méthodes Statiques qui ne traitent pas les propriétés statiques doivent être des fonctions".
Ces sont tous les deux assez grandes déclarations. Si j'ai un ensemble de fonctions qui sont liées à la matière, mais les données de l'instance est totalement inapproprié, je préférerais les avoir définies dans une classe et pas chacun d'entre eux dans l'espace de noms global. Je suis juste à l'aide de la mécanique disponible en PHP5 pour
c'est juste un moyen pratique d'appliquer plus de cohésion et plus faible couplage.
Et FWIW -- il n'y a pas une telle chose, au moins en PHP5, que "les classes statiques"; les méthodes et les propriétés peuvent être statiques. Pour empêcher l'instanciation de la classe, on peut la déclarer abstraite, aussi.
D'abord vous demander, qu'est-ce que cet objet va représenter? Une instance de l'objet qui est bon pour les opérations sur les ensembles distincts de données dynamiques.
Un bon exemple serait l'ORM ou couche d'abstraction de base. Vous pouvez avoir plusieurs connexions de base de données.
Les deux connexions peuvent désormais fonctionner de manière indépendante:
Maintenant à l'intérieur de ce paquet/bibliothèque, il y a peut être d'autres classes telles que Db_Row, etc. pour représenter une ligne spécifique retourné par une instruction SELECT. Si cette Db_Row classe était une classe statique, alors ce serait être en supposant que vous n'avez qu'une ligne de données dans une base de données et il serait impossible de faire ce que l'instance d'un objet pourrait. Avec une instance, vous pouvez maintenant avoir un nombre illimité de lignes dans un nombre illimité de tables dans un nombre illimité de bases de données. La seule limite est le matériel du serveur ;).
Par exemple, si la méthode getRows sur la Db objet renvoie un tableau de Db_Row objets, vous pouvez maintenant utiliser sur chaque ligne indépendamment l'un de l'autre:
Un bon exemple d'une classe statique serait quelque chose qui gère les variables de registre, ou des variables de session car il n'y aura qu'un registre ou une session par utilisateur.
Dans une partie de votre application:
Et dans une autre partie:
Depuis il n'est jamais va être un utilisateur à la fois par session, il n'y a pas de point dans la création d'une instance de la Session.
J'espère que cette aide, ainsi que les autres réponses pour aider à clarifier les choses. Comme une note de côté, découvrez "la cohésion" et "couplage". Ils présentent de très, très bonnes pratiques à utiliser lors de l'écriture de votre code qui s'appliquent à tous les langages de programmation.
Si votre classe est statique, ce qui signifie que vous ne pouvez pas passer son objet à d'autres classes (car il n'existe aucune instance possible) ce qui signifie que tous vos classes seront directement à l'aide de cette classe statique qui signifie que votre code est désormais étroitement couplé avec la classe.
Couplage de votre code moins réutilisable, fragile et sujet à des bugs. Vous voulez éviter les classes statiques pour être en mesure de passer instance de la classe à d'autres classes.
Et oui c'est un seul de beaucoup d'autres raisons dont certaines ont déjà été mentionnées.
En général, vous devez utiliser des variables et des fonctions de membre, sauf si elle doit absolument être partagée entre toutes les instances ou à moins de créer un singleton. À l'aide des données sur les membres et les fonctions de membre vous permet de réutiliser vos fonctions de plusieurs pièces différentes de données, alors que vous ne pouvez avoir qu'une seule copie de données sur lequel vous travaillez, si vous utilisez des données statiques et des fonctions. En outre, bien que pas aussi applicable à PHP, les fonctions statiques de données et de conduire à un code non réentrant, tandis que la classe de données facilite la réentrée.
Je tiens à dire qu'il n'y est certainement un cas où je voudrais variables statiques - dans les applications de langage.
Vous pourriez avoir une classe que vous passez d'une langue à l' (par exemple $_SESSION['langue']) et qu'il accède à d'autres classes qui sont conçus comme suit:
À l'aide de Cordes::getString("somestring") est une belle manière de résumé de votre utilisation de la langue de votre application. Vous pourriez faire quand vous le voulez, mais dans ce cas, chaque fichier de chaînes ont des constantes de chaîne de valeurs qui sont utilisées par les Chaînes de la classe fonctionne assez bien.