L'appel de la variable directement la propriété vs lecture/définition - OOP de Conception
Je sais que c'est sans doute subjectif, mais j'ai lu ce optimisation de la page de Google pour PHP et ils suggèrent d'utiliser la variable directement la propriété sans la nécessité de getters et setters. Naturellement je vois le gain de performance dans ce mais est-ce vraiment une bonne pratique de conception à suivre?
Leur Exemple à l'aide de getter/setter:
class dog {
public $name = '';
public function setName($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
}
$rover = new dog();
$rover->setName('rover');
echo $rover->getName();
Suggéré D'Optimisation:
$rover = new dog();
$rover->name = 'rover';
echo $rover->name;
Ce serait un changement bienvenu dans mon processus de création que je vois la nécessité pour les getters/setters de s'en aller, mais quels sont les autres obstacles/avantages peuvent se produire en faisant cela?
- Gardez à l'esprit que ce tutoriel est un peu daté. C'est probablement toujours d'actualité 5.3, mais la performance n'est pas vraiment le sujet ici. Je voulais recommander Berrys post sur les getters/setters de nouveau, mais j'ai remarqué que vous le savez déjà..
- L'article que vous avez lié a été écrit par une personne ignorant de PHP internals ou c'est vraiment obsolète. Quelques conseils il y a au moins est simplement faux. C'est une honte de quelque chose comme cela peut porter Googles nom.
- ouais j'aime vraiment Berrys post sur le sujet, vraiment essayer de couper vers le bas sur le code inutile.
- naturellement il y a certaines choses que je ne sois pas d'accord avec sur la page moi-même, pourriez-vous en dire un peu plus?
- Pafford: L'auteur (pour je ne sais quelle raison) pense que
$x = ...; echo $x
utilise deux fois plus de mémoire que l'utilisation deecho ...;
directement. - Pafford Merci les gars, vraiment apprécier ça! Ne savais pas que mon blog a été très populaire. 🙂
- Le lien vers Google est aujourd'hui brisé
Vous devez vous connecter pour publier un commentaire.
Un passe-partout de réponse, j'ai peur, mais je vous propose le texte suivant:
Si vous n'avez pas l'encapsulation des problèmes pour votre classe (l'application de la logique d'entreprise, etc.) en exposant cette propriété à d'autres utilisateurs, il est parfaitement ok pour le faire.
Vous perdre la capacité de mettre en place des get/set logique sur une propriété particulière. Pour les propriétés qui sont des scalaires (chaînes de caractères, des entiers, des booléens) peut-être que ce n'est pas un problème. Mais que faire si vous avez une propriété qui est un chargement paresseux instance de classe?
Cette astuce ne fonctionne que dans une méthode. Vous pouvez utiliser
__get
et__set
pour cette logique, mais à mesure que vous ajoutez des propriétés de vous retrouver avec un gros méchantswitch()
bloc:Si vous voulez juste pour éviter ou à remettre à l'écriture des getters et setters, utilisez le
__call
méthode magique pour intercepter les appels de méthode qui suivent lagetProperty()
etsetProperty()
convention de nommage. Vous pouvez mettre tous les défaut get/set logique dans__call
et de ne jamais toucher à nouveau:Cette approche est très rapide à partir d'un développement point de vue parce que vous pouvez simplement étendre la classe de l'Objet, de définir certaines propriétés, et vous êtes hors de la course:
C'est lent à partir d'un exécution point de vue parce que les méthodes magiques sont damnés lent, mais vous pouvez atténuer que, plus tard, par la définition explicite
getBar()
etsetBar()
méthodes (parce que__call
est invoqué lorsque vous appelez une méthode qui n'est pas défini). Mais si une propriété n'est pas d'obtenir un accès très souvent, peut-être que vous ne se soucient pas comment lent, il est. Le point est, il est facile d'ajouter des méthodes get/set plus tard, et le reste de votre code ne sait jamais la différence.J'ai chipé cette approche de Magento et je trouve que c'est très abordable pour les développeurs. Lancement d'une exception lors de l'appel de la get/set pour une propriété qui n'existe pas, vous aide à éviter fantôme de bugs causés par les fautes de frappe. Conserver les biens logique spécifique dans ses propres méthodes get/set rend le code plus facile à maintenir. Mais vous n'avez pas à écrire toutes les méthodes d'accès au début, vous pouvez facilement revenir en arrière et ajouter sans refactoring tous vos autres code.
La question est-ce que vous essayez d'optimiser? Le temps du développeur ou du code de la vitesse? Si vous souhaitez optimiser le code de vitesse, assurez-vous que vous savez où votre goulets d'étranglement avant de construire votre code autour d'eux. L'optimisation prématurée est la racine de tous les maux.
C'est une sorte de micro-optimisation. Théoriquement, vous pouvez ensuite ajouter de la logique sur le nom de get/set en utilisant les méthodes magiques (__get et __set), mais pratiquement, il n'est pas besoin de tant de choses. Et encore, dans la pratique, cette amélioration des performances seulement important que si vous avez tout le reste de manière optimisée, que même quelques microsecondes ajouter de la valeur. Dans ce cas, vous pouvez utiliser d'autres techniques d'optimisation comme la fusion de tous les fichiers PHP dans une, supprimer le type conseils, diminuer le nombre de paramètres de la fonction, utiliser les fonctions ordinaires au lieu de classes. Mais généralement l'ajout d'une simple mise en cache ajoute les 10-100x boost de performance que tous ces micro-optimisations.
Vous pouvez également utiliser l' __get et __set méthodes magiques:
J'ai d'abord été surpris, j'étais comme ... wtf. Mais après avoir décroché mon cerveau sur elle quelques secondes, j'ai réalisé l'exemple appelle la fonction get de 1 million de fois en boucle. Bien sûr, si la variable est enveloppé dans un getter, nous avons ajouté des instructions et bien sûr, il va prendre plus de temps.
À mon avis, dans la plupart des situations, cela est très médiocre, car je n'ai pas encore trouvé un script qui vient d'événement proche de l'appel de getters 1 millions de fois lors de l'exécution. Si vous ne besoin de serrer la performance à la dernière goutte, il est bon de savoir que ce type d'optimisation technique.
Cela dépend si
$name
est public ou pas. Si elle ne l'est pas, vous ne pouvez pas accéder/modifier directement. Le compromis est d'exposer votre classe interne des éléments de données directement aux intégrateurs. Cela peut être OK pour certaines classes, mais pas pour d'autres.Par exemple, vous ne pouvez pas forcément envie à d'autres d'être en mesure de modifier le prix d'un produit directement dans un
Product
classe.Je dirais que c'est vraiment une question de préférence personnelle. Si la performance est vraiment que important, puis je pense que vous avez répondu à votre propre question.
Cependant, dans votre premier exemple, vous pouvez toujours accéder à
dog::name
sans les getter/setter comme vous le feriez dans votre deuxième exemple:$rover->name = 'rover';
parce que$name
est public.Si vous souhaitez masquer un membre de la classe, vous devez déclarer la variable
private
ouprotected
et puis un getter/setter serait nécessaire.