11
votes

Pouvez-vous avoir trop de "dynamique" dans des langues dynamiques?

Au cours des derniers mois, je fais une transition de Java à Groovy et je peux apprécier de nombreux avantages qu'il apporte: moins de code, de fermetures, de constructeurs, de la vadrouille qui, à la fin, constitue un cadre comme des greils éventuels, facilité avec la moqueur Ecriture des tests, etc.

Cependant, j'ai été "accusé" par mes collègues que mon code n'est pas assez groovy. À savoir, je déclare toujours des types pour mes paramètres et champs, ont tendance à utiliser l'héritage et le polymorphisme au lieu de dactylographie de canard, etc. Il me semble que dans ces situations, il n'est pas seulement dynamique vs. dynamique et paradigme dynamique vs orienté objet. genre de dilemme. Dans ces cas, j'ai toujours tendance à préférer OO. Je pense que OO Paradigm a une grande valeur dans sa prémisse de base pour vous permettre de résumer et de relier vos constructions de code sur des concepts réels particuliers.

Alors, voici des questions particulières dont j'ai besoin d'aide avec:

  1. devrais-je déclarer des types pour mes paramètres, champs, etc.

  2. Devrais-je déclarer bloc de code comme fermeture lorsque la méthode simple fera?

  3. Quand dois-je utiliser la frappe de canard au lieu d'une expédition dynamique polymorphe. Par exemple, à Groovy, je peux faire des animaux. "$ Action" () ou def def; animal.action (), au lieu de l'animal animal = nouveau chien (); animal.action (). Je peux voir le problème avec d'abord dans le contexte de principe ouvert fermé, mais toutes les autres raisons de préférer le polymorphisme de style OO?

  4. Quand dois-je utiliser des interfaces à Groovy (si jamais)?

    Je suis sûr qu'il y a quelques autres dilemmes similaires que je n'ai pas réussi à écrire. Je pense aussi que ces questions sont valables non seulement pour Groovy, mais pour toute autre langue dynamique. Quelle est votre opinion?


1 commentaires

Une autre raison de déclarer des types est la programmation des services Web SOAP afin que la WSDL générée puisse contenir des informations de type ...


6 Réponses :


2
votes

Je pense que avec Groovy, vous devriez privilégier le moyen le plus simple de faire quelque chose et tomber sur les fonctionnalités de Groovier uniquement lorsque la situation l'appelle. (Comme lors de la rédaction de macros ou de créer des multimethods à Clojure, si vous vous retrouvez à ces outils, vous devez vous remettre en question.) Votre approche prudente me semble amende pour moi, éventuellement que vos collègues sont un peu ébriété à leur nouvelle puissance trouvée. . (Ce ne serait pas la première fois.)

La bonne chose à propos d'avoir une langue flexible comme Groovy est que vous pouvez commencer par l'approche prudente comme si vous vous êtes favorable à la connaissance de vous avoir des alternatives plus puissantes à tomber lorsque vous en avez besoin lorsque vous en avez besoin. Vous savez: "La chose la plus simple qui pourrait éventuellement fonctionner."

Préférant plus spécifiquement la typage de canard sur des interfaces et ne pas déranger avec les types de paramètres semble être une bonne chose, il peut s'agir beaucoup plus facile de fournir des simulacres aux tests.


3 commentaires

J'utiliserais habituellement une typing statique où cela a du sens (mon code est conçu pour fonctionner pour un cas spécifique et je ne veux pas offrir aucune autre garantie) et permettre une dynamique partout ailleurs (ou du moins aussi dynamique que possible. accepter de soutenir). Il s'agit davantage de savoir ce que votre code "promet" il ne fait pas que tout le potentiel (MISS | AB) utilise de celui-ci.


Ajoute des types statiques à vos signataires "la manière la plus simple de faire quelque chose"?


@Chuck - Peut-être; Les contraintes peuvent grandement simplifier les choses comme lorsqu'il existe des contraintes appliquées, vous pouvez laisser la raison du compilateur sur quels types sont représentés dans le codeBase plutôt que de tenir cette information dans votre tête.



1
votes

Cela revient à ce que les gens sont à l'aise avec. J'aime utiliser les déchets de type et les appels de méthode parce que je suis à l'aise en Java. Le code que j'écris doit être maintenu par des personnes avec une expérience de programmation beaucoup dynamique, donc je garde à proximité du code Java normal, à moins qu'il y ait une bonne raison d'utiliser une fonctionnalité groovy avancée. On dirait que votre groupe devrait créer des normes de codage qui tentent d'expliquer lorsque des caractéristiques spécifiques de Groovy doivent généralement être utilisées.


1 commentaires

Je dois respectueusement en désaccord. Une réponse dans les lignes de «quelle que soit la jamais» est une réponse non-réponse. En défaut de mettre les types de paramètres dans les définitions de la méthode rend le code beaucoup plus difficile à lire par une nouvelle paire d'yeux. Il est important d'avoir des normes de codage, mais il est plus important d'avoir des normes qui exigent les meilleures pratiques de codage. Et les meilleures pratiques de codage mettent toujours la lisibilité du code comme les critères les plus importants.



6
votes

Ce n'est pas toujours une opinion populaire, mais je pense que le plus explicite et le plus clair que votre code peut être, meilleur.

Je n'aime pas les constructions qui vous laissent deviner juste ce qui se passe ...

J'ai travaillé pendant un an à Ruby et je ne l'aimais pas du tout. Je ne dis pas qu'il n'a pas de place où il excelle, je dis simplement que j'aime beaucoup garder les choses propres et explicites et ne ressentissais pas que Ruby avait cela comme objectif.

Une chose que j'ai trouvée à coup sûr - la quantité de taper que vous ne correspond à la vitesse de développement globale n'est pas assimilée. Il est vrai qu'une base de code compliquée avec beaucoup de code répété effectue un développement très lent, mais il suffit de réduire ce que vous tapez sans éliminer la duplication est inutile et de taper plus longtemps, plus clair, plus de code explicite va généralement être plus rapide (sur le Longueur du projet) que le même code écrit dans une langue terrese, moins formelle.

Si vous ne croyez pas que la dactylographie n'a pas de relation avec la vitesse de développement, la prochaine fois que vous publiez un projet comptent le nombre de lignes de code et divisez par les jours d'homme dépensés (y compris le débogage et les tests). En d'autres termes, combien de code a été saisi par jour. Vous trouverez le résultat d'être un très petit nombre - en réalité la frappe du code est une très petite partie de tout projet logiciel.


2 commentaires

J'aime l'approche opt-in de la dynamique que c # (par exemple) prenait - statique dans la mesure du possible, dynamique lorsque cela est requis ou s'il y a un avantage clair.


Surtout, je pense que votre code dépend de l'équipe. Une bonne équipe peut faire du bon code dans n'importe quelle langue. Une mauvaise équipe peut faire un mauvais code dans n'importe quelle langue - mais incroyablement Bad Code prend une mauvaise équipe, une langue flexible et un programmeur très talentueux ... restreindre le programmeur intelligent du groupe qui trouve une construction qui l'aide à créer "Concise "ou" expressif "du code avant d'apprendre à afficher son code du point de vue du prochain programmeur est probablement la meilleure chose qu'une langue puisse faire.



-1
votes

oui

-

NON

Réalisez-vous qu'il n'y a pas de réponse réelle pour cette question?


2 commentaires

Et que le mien aurait dû être un commentaire à la place?


Je ne pense pas que tous les points sont à la hauteur des préférences personnelles. Par exemple animal. "$ Action" () pause OCP; une raison suffisante pour préférer le polymorphisme.



0
votes

Il existe deux types dominants de langues orientées objet.

Les langues dans la famille SIMULA 67 FAMILLE, telle que C ++ et JAVA, favorisez des variables, des compilateurs et des liaisons typiques statiquement, et des vtables de méthode.

Les langues dans la famille SmallTalk , telle que RUBY, favoriser des variables, une interprétation, une interprétation et un message de messages dynamiquement au lieu de tables de pointe-pointeur.

Les deux sont orientés objet, mais très différents prend le concept d'orientation objet.


0 commentaires

1
votes

.1. Devrais-je déclarer des types pour mes paramètres, champs, etc.

J'ai tendance à déclarer des types de classes utilisées dans le cadre d'une API publique, des choses que d'autres développeurs vont consommer beaucoup, ou où j'aimerais une aide supplémentaire automatique de Intellij. Sinon je 'def' def '.

.2. Devrais-je déclarer bloc de code comme fermeture lorsque la méthode simple fera?

J'utilise des méthodes à moins que ce soit quelque chose que je prévois de passer autour de la variable. Même s'il y a la méthode «FOO. & BAR» Opérateur de désareférence, la plupart des Devs ne savent pas cela et sont confondus par celui-ci lorsqu'ils le courent. J'utilise également des fermetures quand il s'agit d'un petit morceau de code qui est clair pour rester dans une méthode plus grande plutôt que de placer sa propre méthode de descriptive descriptive.

.3. Quand devrais-je utiliser la typing de canard au lieu d'une expédition dynamique polymorphe. Par exemple, à Groovy, je peux faire des animaux. "$ Action" () ou def def; animal.action (), au lieu de l'animal animal = nouveau chien (); animal.action (). Je peux voir le problème avec le problème d'abord dans le contexte du principe ouvert fermé, mais toutes les autres raisons de préférer le polymorphisme de style OO?

Je n'utilise que l'animal. "$ Action" () Formulaire lorsque j'ai besoin de ce niveau d'indirection, car le nom de la méthode varie en fonction du chemin d'exécution du code (le plus souvent pendant les métaprogrammations lourdes). J'utilise animal animal = nouveau chien (); animal.acte () Lorsque je souhaite l'aide de l'IDE avec l'autocompletion ou que le niveau de documentation est utile pour la clarté du code (et non blessé par le verbauless supplémentaire qui pourrait être évident ou contraignant).

.4. Quand devrais-je utiliser des interfaces à Groovy (si jamais)?

Je les utilise très rarement. Je pouvais voir les utiliser principalement en tant que documentation des champs attendus d'un appel public d'API, ou éventuellement en tant qu'interface de marqueur pour aider à distinguer un ensemble de classes d'un autre à partir d'une perspective de métaprogramming. Ils sont beaucoup moins utiles à Groovy qu'à Java.


0 commentaires