Le static, c’est pas automatique ?

(1479 mots)

Sujet intéressant je trouve, voici donc mon partage 🙂

Le static, par définition

Le fait de déclarer des propriétés ou des méthodes comme statiques vous permet d’y accéder sans avoir besoin d’instancier la classe. Source

Procédural et objet

Il peut arriver que l’on pense faire la programmation orientée objet (POO) dès qu’on utilise des classes ou que l’on écrit :

$objet->prima_method($args)

ce qui est faux mais malheureusement pas toujours évident sad

C’est probablement parce que le mot « procédural » fait penser à ça instinctivement :

$func = my_function($args);

et, qu’à l’inverse, dès que l’on va voir la fameuse flèche et l’utilisation de méthodes provenant d’une classe instanciée, on va penser qu’il y a de la POO derrière. Ce qui est encore faux, du moins pas nécessairement vrai.

Le fait de prendre par exemple my_function() et de la mettre dans une classe ne suffira pas à faire de la POO. Le code pourra très bien rester procédural. La POO suit des patterns, des modèles de code.

La clé pour distinguer le vrai du faux AMHA c’est de poser le sujet en ces termes :

Le procédural et la POO sont des approches pas des modes d’écriture ou des figures de style.

Remarque : vous aurez noté l’utilisation des « et » dans mon titre et pas des « vs » comme on peut le lire parfois « procédural vs POO ».

Et le static dans tout ça ?

Une méthode statique dans une classe, c’est un peu comme la fonction dont je parle plus haut, imaginons qu’on l’ait posée sans autre action supplémentaire dans une classe,  on aurait :

My_Class {
    public static function my_function($args) {}
}

et pour l’appeler on ferait :

$static_call = My_Class::my_function($args);

La différence avec un :

$call = my_function($args);

Ici on pourrait même dire que je n’ai fait que « namespacer » ma fonction smile

Passer par du statique permet de ne pas se soucier du contexte. Le résultat de la fonction sera toujours le même, sans influence extérieure, sans effet secondaire, si on passe les mêmes $args.

Dans le jargon on parle de fonctions stateless _ce qui est équivalent à _sans contexte. En cela, on se rapproche beaucoup plus du procédural que de l’objet, rien avoir même ici et pourtant on a écrit une classe.

D’ailleurs, dans une méthode statique, il est par définition impossible d’utiliser $this. La méthode s’utilise sans instancier la classe, sans donc créer un objet.

C’est quoi le souci avec le statique alors ?

Le statique est souvent décrié et malheureusement souvent au motif que tout devrait être objet ce qui est peut-être génial dans l’idée mais très peu convaincant au final. Toutes les opérations n’ont pas besoin d’objet, loin s’en faut.

Un argument plus important est celui des unit tests car il n’est pas trivial de remplacer la référence d’une méthode statique par autre chose, c’est compliqué même. Le grand nombre de cas de mauvaise utilisation n’apporte pas d’eau au moulin des partisans du statique. Et enfin un 3ème argument qui découle des deux derniers :

LA COMPLEXITÉ. Une application truffée de méthodes statiques rajouterait de la complexité inutilement puisque contrairement à la POO, on aura pas accès à l’ensemble des actions possibles (méthodes) depuis un objet mais bien souvent à des méthodes éparpillées à droite à gauche. Le risque d’erreur serait donc accru et la maintenance plus complexe si on suit ce raisonnement.

Donc quand utiliser du statique et quand éviter ?

Commençons par le mauvais, on finira sur une bonne note je l’espère. L’argument est le suivant :

une méthode statique n’a, par définition pas le même état que la classe qui la contient, elle est là sans être vraiment là. Elle ne dépend pas vraiment de la classe. On peut l’appeler de n’importe où, comme une globale.

J’ai dit un gros mot ? lol

Je taquine mais pas vraiment en fait, on aura bien créé une procédure globale. Deuxième grot mot ?

Prenons un exemple plus parlant. Je décide de créer une méthode statique qui va incrémenter un compteur et une autre qui me servira à afficher le résultat. On comprend déjà dans cette phrase le souci. Comme ma méthode est statique, elle accessible partout, si un autre développeur l’utilise, il va me pourrir mon résultat et là on sera loin mais alors très très loin du côté pas d’effet secondaire.

Mise en image :

My_Class::update_counter( 19 );
$counter = My_Class::get_count();

Typiquement ici on aurait plutôt besoin du côté stateful autrement dit d’un contexte ! Logiquement on se tournerait vers l’objet :

$obj = new My_Class();
$obj->update_counter( 19 );
$counter = $obj->get_count();

J’ai contextualisé mon code, il n’y aura plus de problème à l’utiliser dans d’autres parties du code sans effet de bord.

Côté variable

On a pas encore parlé des variables ! J’ai commencé par les méthodes mais les variables statiques ont aussi leur utilité. En réalité, la différence entre :

global $my_global_var;

et :

public static $my_global_var;

que l’on peut voir dans certaines classes, est minime. Les deux seront accessibles de partout, à niveau global.

Reparlons de compteurs

Contrairement aux variables locales classiques qu’on définit dans les fonctions, une variable static ne sera pas détruite au moment de l’exit. Et si on utilise à nouveau la fonction, ailleurs, elle conservera sa valeur. L’exemple style Hello World que l’on donne souvent est de créer un compteur qui incrémente chaque fois qu’une fonction est utilisée quelque part dans le code :

function _do_something() {
 static $count = 0;
 var_dump($count);
 $count++;
}

_do_something();
_do_something();
_do_something();

$count va bien s’incrémenter pour valoir 3 au final dans cet exemple.

WordPress, le static et les singletons

Mise à jour du 22 mai 2018

Dans cette partie que je viens de supprimer je faisais non pas l’apologie mais en tout cas la démo que le singleton pouvait convenir à WordPress. C’était une erreur et malgré toutes les précautions prises dans ma manière de le présenter, il y avait un petit côté :

arrêtez de dire du mal du singleton

J’avais bien conscience que ce n’était pas bien, mais attention au sens de « pas bien » ici, ça veut dire erreur de design, violation de certains principes sacrés du dév, ce qui évidemment n’est pas bien mais ne se voit pas tout de suite, de manière triviale comme une erreur fatale ou un warning.

Aujourd’hui j’ai changé, un homme nouveau XD, et je conseillerais plus de faire du procédural bien fait sans classes ni objet plutôt que de passer par du singleton, pourquoi parce que dès le moment où on va devoir mettre en place des tests, faire évoluer des grosses « machines » (gros projets) ça dresse des murs.

Évitez-les donc et même pour des projets qui semblent basiques cela restera valable et vous paraîtra même plus simple et lisible que vos anciennes approches.

Cheers et mea culpa donc 😉

Conclusion

Le statique n’est pas le MAL. Cela a beau être mal compris et/ou méconnu, l’utiliser pour ajouter des filtres et des actions n’a rien d’erroné en soi, ce n’est, en revanche, pas vraiment adapté à la modernité, c’est incontestable, sans compter les difficultés qui se posent en matière de units tests et autres.

Ne pas oublier pourquoi on utilise du WordPress et surtout tout ce qu’on peut faire avec ! Nous sommes les premiers à critiquer notre outil, et croyez-moi ça râle ^^.

Il y a une vraie cohérence dans tout ça, la seule chose à faire c’est rester constructif, positif et éviter la politique, donc contribuer, patcher chacun à sa mesure, et faire avancer les choses.

Sélection de liens

Dans la même veine, tu peux aussi lire :

Les commentaires sont fermés.