Il s'est avéré qu'au cours des dernières années, j'ai cousu Frankenstein et non sculpté de jolies figurines en porcelaine de bergères et de ramoneurs. Je crée des solutions basées sur Magento 2. Cela signifie que le matériel source pour moi est le rêve de tout archéologue. La couche culturelle avec des traces de diverses "époques" et "civilisations". Il peut être utilisé pour étudier le développement de la pensée des programmeurs dans les communautés PHP / JS au cours de la dernière décennie.
Et ce n'est que la base, et l'add-in est des modules tiers qui doivent être intégrés à l'intérieur. Ici, il est déjà possible de rencontrer des manifestations d'intelligence extraterrestre. Certains modules sont créés par des créatures développées, très similaires dans leur pensée aux créateurs de la base, mais vous tombez sur ceux que vous voulez prendre l'auteur par l'épaule, regardez profondément dans ses yeux et demandez amicalement: " De quelle planète êtes-vous originaire? "

Le débogueur aide à assembler Frankenstein à partir d'un tel matériau. Ci-dessous est ma technique de codage personnel, qui peut compliquer la vie de toute personne qui, comme moi, utilise le débogueur quotidiennement dans sa vie. Il est petit, avec quatre positions, mais chaque fois que je rencontre quelque chose comme ça lors du débogage, je suis triste. Peut-être que mon message réduira le nombre de peines dans le monde, ou peut-être pas. Je vais au moins essayer.
Obfuscation et cryptage de code
C'est hors compétition. J'ai rencontré plusieurs fois des modules pour lesquels ionCube est nécessaire, et je peux dire que la dernière chose que je ferai est de mettre un module similaire dans mon projet. Je soutiens pleinement la minification du code JS, surtout lorsque la source habituelle est à proximité, mais l'obfuscation et le cryptage sont un mal distillé et concentré. Je vous le dis en tant qu'intégrateur.
IV. Code sur une seule ligne
Économiser sur des lignes de code est le plus inoffensif de ma liste:
if ($cond) aaa(); else bbb();
Raccroche deux étapes sur cette ligne lors de l'exécution pas à pas du programme (calcul de la condition, exécution de la branche true
ou false
). C'est bon, il vous suffit de garder à l'esprit le nombre de fois que vous avez effectué un pas sur cette ligne et de suivre la valeur de $cond
dans la liste des variables. Au fil du temps, l'automatisme s'est développé.
Un peu pire est que vous ne pouvez pas définir un point d'arrêt inconditionnel sur la branche true
ou false
. Au lieu d'un simple clic dans l'EDI, vous devrez travailler avec la souris / le clavier un peu plus longtemps, en ajoutant un point d'arrêt conditionnel.
L'option idéale est lorsque chaque étape exécutable (condition, true
-light, false
-light) est sur sa propre ligne:
if ($cond) aaa(); else bbb();
III. Résultat d'expression
Utilisation d'expressions dans des conditions:
if (exp()) ...
cycles:
foreach (exp() as $item) ...
comme paramètres:
foo(exp(), ...)
et résultat de retour:
return exp();
non seulement rend le code "plus dense", le rend plus facile à comprendre, mais rend également le débogage plus difficile - vous ne voyez tout simplement pas les valeurs d'exécution des expressions dans la liste des variables du débogueur. Je dois ajouter des montres (une question intéressante, et si vous surveillez les générateurs via des montres, cela affectera-t-il l'exécution du programme? ).
L'option idéale est une variable temporaire:
$exp = exp(); if ($exp) ...
II. De nombreux points de sortie
Plusieurs fois, je suis tombé sur la recommandation de n'avoir qu'un seul point de sortie de la fonction et plusieurs fois j'ai rencontré une violation de cette recommandation (un exemple inventé, mais typique):
public function onEvent($event) { if($event == 'entrance') { return 'entranceRoute'; } else if($event == 'exit') { return 'exitRoute'; } return 'defaultRoute'; }
Voici une option plus correcte:
public function onEvent($event) { $result = 'defaultRoute'; if($event == 'entrance') { $result = 'entranceRoute'; } else if($event == 'exit') { $result = 'exitRoute'; } return $result; }
C'est tout, je n'ai pas besoin de disperser les points d'arrêt à chaque return
ou de faire un pas en avant à partir de la première ligne (si le code appelant me donne l'opportunité de voir le résultat dans une variable distincte) pour comprendre comment l'exécution s'est terminée. Imaginez une fonction avec 120 lignes et 22 retours à l'intérieur? Et j'ai déboulonné cela moi-même et je soupçonne que ce n'est pas la limite.
I. Appels de méthode en cascade
Mon préféré est la méthode en cascade :
$collection ->addFilterByProduct(...) ->addShowInStoresFilter(...) ->addPublicFilter(...) ->addApprovedStatusFilter(...) ->addCreatedAtLessThanNowFilter(...);
Si je dois entrer dans la méthode addApprovedStatusFilter()
, qui est basée sur une interface et implémentée dans plusieurs classes différentes (une classe spécifique est déterminée au moment de l'exécution), la chose la plus simple consiste à définir un point d'arrêt sur $collection
et à parcourir tout à son tour ( addFilterByProduct
, addShowInStoresFilter
, addPublicFilter
) au bon endroit. Si vous combinez cela à l'aide d'expressions dans les paramètres et les résultats renvoyés, le chemin d'accès ne se ferme pas complètement. Dans l'original, ce code ressemble à ceci:
$collection ->addFilterByProduct($this->getProduct()) ->addShowInStoresFilter($this->_storeManager->getStore()->getId()) ->addPublicFilter() ->addApprovedStatusFilter() ->addCreatedAtLessThanNowFilter();
Oui, avec les méthodes en cascade, le code devient plus lisible, mais le débit devient plus difficile. Je n'ai rien contre la cascade de set'er (moi, en règle générale, je ne fais pas mes débuts):
$answerModel ->setAuthorName(...) ->setStatus(...) ->setCreatedAt(...) ->setAuthorEmail(...) ->setCustomerId(...) ->setHelpfulness(...)
Mais le code qui contient la logique qui peut devoir être débité, ou peut-être même par moi-même, vaut mieux écrire " old school " (je le fais moi-même):
$collection->addFilterByProduct(...); $collection->addShowInStoresFilter(...); $collection->addPublicFilter(...); $collection->addApprovedStatusFilter(...); $collection->addCreatedAtLessThanNowFilter(...);
Est-il devenu beaucoup plus difficile à percevoir?
Ou voici les recommandations pour un bon style de programmation:
ladder.up().up().down().up().down().showStep();
Regardez cela du point de vue d'un intégrateur, qui devrait pénétrer dans le second.
Résumé
Je ne veux pas dire que ces techniques sont utilisées dans leur code par des « extraterrestres ». Pas du tout, pour la plupart, au contraire, ils visent à réduire la quantité de code. Mais ces techniques compliquent le débogage. Une personne n'a pas la vitesse d'un ordinateur, et pour atteindre le code du problème, l'intégrateur doit d'abord scanner (ne pas comprendre, à savoir scanner) la progression du programme à des points clés. Tout ce qui précède, ayant d'une part la tâche d'améliorer la compréhension du code, en fait, lors du débogage, cette compréhension est entravée. Ils n'interfèrent pas à l'emplacement du code, mais interfèrent avec l'accès à la zone à problème, qui, en général, nécessite une réelle compréhension.
Clause de non-responsabilité
Ce qui précède est le résultat d'une déformation professionnelle personnelle et peut différer des opinions basées sur d'autres déformations professionnelles.