Existe-t-il un contre-modèle pour décrire cette méthode de codage? [fermé]


26

J'ai une base de code où le programmeur avait tendance à boucler les choses dans des domaines qui n'ont pas de sens. Par exemple, étant donné un journal d'erreurs que nous avons, vous pouvez vous connecter via

ErrorLog.Log(ex, "friendly message");

Il a ajouté divers autres moyens pour accomplir exactement la même tâche. PAR EXEMPLE

SomeClass.Log(ex, "friendly message");

Ce qui se retourne simplement et appelle la première méthode. Cela ajoute des niveaux de complexité sans aucun avantage supplémentaire. Existe-t-il un anti-modèle pour décrire cela?


36
"Bad coding" le couvre;)
Oded

12
Dépend. Est-ce un wrapper pour une bibliothèque de journalisation? S'il y a jamais eu une chance qu'il puisse être échangé, c'est en fait une bonne pratique ...
Rig

3
@lortabac: Le problème avec le "code baklava" est qu'il semble vraiment bon et savoureux, et donc souhaitable.
FrustratedWithFormsDesigner

10
Que dit ce programmeur lorsque vous les ajoutez, pourquoi ajoutent-ils ces méthodes? La compréhension de leur raisonnement devrait faciliter leur éducation.
Keith

3
Cela ressemble à un niveau d' indirection , ce qui peut être bon lorsque vous voulez éviter le couplage entre deux classes, comme l'a souligné @Rig. Peut-être que c'était juste un codeur souffrant de patternitis - essayant simplement un pattern pour résoudre un problème qui n'est pas là, violant KISS.
Fuhrmanator

Réponses:


54

Il ne vaut la peine d'appeler une mauvaise habitude de codage un Antipattern que si elle est raisonnablement répandue.

Le reste que nous appelons simplement "code poubelle" ...


Si je devais suggérer un nom pour cette mauvaise habitude, ce serait "Trouble obsessionnel de l'abstraction" :-)


9
J'ai toujours utilisé "Indirection Hell".
Dan Neely

27

Non, ce n'est pas un anti pattern mais je voudrais soulever les problèmes suivants.

Violation du principe de responsabilité unique

SRP dit qu'une classe devrait avoir une raison de changer. L'ajout d'une méthode de journalisation signifie que la classe doit également changer si la logique de journalisation doit être modifiée.

Violation d'un is-a relation

Les classes de base ne sont pas des boîtes à outils dans lesquelles vous pouvez ajouter plusieurs méthodes pratiques.

Cela permet de coupler efficacement toutes les classes héritées aux implémentations de la classe de base.

Comparez cela avec la composition.


1
"Problème de responsabilité unique"? SRP? Peut-être que vous vouliez écrire le principe de responsabilité unique? Il suffit de connecter les deux ici. :)
zxcdw

8

Non pas que cela le rend acceptable, mais cela pourrait simplement être une refactorisation inachevée. Peut-être que SomeClass.log () avait sa propre logique et a été implémenté en premier. Et plus tard, ils ont réalisé qu'ils devraient utiliser ErrorLog.Log (). Ainsi, plutôt que de changer 100 emplacements où SomeClass.Log () est appelé, ils ont simplement délégué à ErrorLog.Log (). Personnellement, je changerais toutes les références à ErrorLog.Log () ou au moins commenter SomeClass.log () pour dire pourquoi il délègue la façon dont il le fait.

Juste quelque chose à considérer.



4

Je ne suis pas sûr de décrire cela comme une infraction au principe de responsabilité unique, car s'il y a un changement dans la signature de la méthode ErrorLog (la méthode appelée par SomeClass), chaque code client qui appelle cette méthode échouera.

Il existe évidemment un moyen d'utiliser l'héritage (ou de créer des classes nécessitant une journalisation en implémentant une interface de journalisation).


Encore une mauvaise pratique car: 1) il est peu probable que cela change 2) si cela change, ils peuvent simplement construire une classe wrapper avec le même nom et modifier les importations.
kevin cline

2
+1. Et voici "Oncle Bob" (Robert Martin) plaidant en faveur de la centralisation des dépendances dans un nombre limité de modules, plutôt que de les disperser dans le code.
MarkJ

3

Ou nous pourrions considérer cela comme un "moment d'apprentissage" :)

Votre développeur est peut-être à mi-chemin d'une bonne idée. Supposons que vous souhaitiez exiger que tous vos objets métier soient capables d'une journalisation intelligente. Vous pouvez définir:

   public interface IBusinessObjectLogger
   {
       void Log(Exception ex, string logMessage)
   }

Désormais interne à vos objets, vous pouvez utiliser l'objet ErrorLog pour effectuer réellement la journalisation tandis que le code SomeClass ajoute une valeur spécifique à l'objet au message de journal. Vous pouvez ensuite étendre davantage vos API de journalisation pour implémenter la fonctionnalité de journalisation basée sur des fichiers, des bases de données ou des messages sans toucher à vos objets métier.


3

Je ne suis pas sûr que ce soit automatiquement mauvais.

Si vous appelez SomeClass.Log, c'est certainement mal, mais si Log est uniquement utilisé à partir de WITHIN SomeClass, cela coupe le couplage et je l'appellerais acceptable.


2

Ceci est en fait assez courant dans certains styles de codage, et les bases de la ligne de pensée ne sont pas, en elles-mêmes, un anti-modèle.

C'est très probablement le résultat d'un codage par nécessité sans connaissance de la base de code plus large: "OK, ce code doit enregistrer une erreur, mais cette fonction n'est pas l'objectif principal du code. Par conséquent, j'ai besoin d'une méthode / classe qui le fera pour moi". C'est une bonne façon de penser; mais, sans savoir que ErrorLog existait, ils ont créé SomeClass. Ils ont ensuite trouvé ErrorLog à un moment ultérieur, et plutôt que de remplacer toutes les utilisations de la méthode qu'ils avaient mise, ils ont appelé leur méthode ErrorLog. C'est là que cela devient un problème.


2

Complexité accidentelle est la complexité qui survient dans les programmes informatiques ou leur processus de développement qui n'est pas essentielle au problème à résoudre. Alors que la complexité essentielle est inhérente et inévitable, la complexité accidentelle est causée par l'approche choisie pour résoudre le problème.

http://en.wikipedia.org/wiki/Accidental_complexity


1

Il peut s'agir d'un abus / d'une mauvaise compréhension du modèle de façade . J'ai vu des choses similaires dans une base de code avec laquelle j'ai travaillé. Les développeurs sont passés par une phase où ils étaient fous des modèles de conception sans comprendre les principes généraux de la conception OO.

Une mauvaise utilisation du motif de façade entraîne un flou des niveaux d'abstraction à travers les couches de l'application.


1

Ce que fait ce programmeur, c'est encapsuler du code, afin qu'il n'ait pas de dépendance directe sur le module de journalisation. Sans informations plus spécifiques, il n'est pas possible de donner un modèle plus spécifique. (Que ces emballages ne soient pas utiles est votre opinion qui est impossible à approuver ou à refuser sans beaucoup plus d'informations.)

Les modèles auxquels cela peut appartenir sont Proxy , Délégué , Décorateur , Composite ou certains de ceux qui ont trait à l'habillage, au masquage ou à la distribution des appels. Il peut être l'une de ces choses dans un état de développement incomplet.


0

Je pourrais imaginer que ce soit une différence culturelle. Il y a peut-être une bonne raison d'avoir des fonctionnalités en double dans cette base de code particulière. Je pourrais imaginer la facilité d'écriture comme une telle raison. Le programmeur Python en moi dirait toujours que c'est mauvais, car " Il devrait y en avoir un - et de préférence un seul - une manière évidente de le faire ", mais certains gars de Perl pourraient être habitués au fait qu'il y en a plus d'un façon de le faire ".


1
La facilité d' écriture initiale n'est pas une bonne raison de duplication. Un mauvais code peut être plus facile à écrire la première fois, mais cela ne facilite pas l'écriture de code à long terme. Que fait le nouveau venu avec la fonctionnalité dupliquée? Quelle méthode appelle-t-il? Il perd son temps à les chercher et à les lire, seulement pour découvrir qu'ils font la même chose.
Kazark

Peut-être que ce code était à l'origine conçu comme un prototype qui a ensuite été utilisé (ab) comme incrément. Dans ce cas, l'optimisation pour l'écriture initiale aurait été valable, je pense.
Bengt
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.