Je regardais le framework WPF MVVM Caliburn.Micro et j'ai lu que beaucoup de choses standard sont basées sur conventions de nommage .
Par exemple, la liaison automatique des propriétés de la vue aux propriétés du ViewModel. Bien que cela semble être pratique (supprime du code passe-partout), ma première réaction instinctive est que ce n'est pas complètement évident pour un nouveau programmeur qui lira ce code. En d'autres termes, la fonctionnalité de l'application n'est pas complètement expliquée par son propre code, mais aussi par la documentation du framework.
MODIFIER:
Cette approche est donc appelée convention sur la configuration. Comme je n'ai trouvé aucune question à ce sujet, j'ai modifié ma question:
Ma question est:
La convention sur la configuration est-elle une manière correcte de simplifier les choses ou viole-t-elle certains principes de programmation (et si oui, lesquels)?
Je ne considère pas "qu'une application doit être entièrement expliquée par son propre code" un principe de programmation fondamental. Il y a beaucoup, beaucoup de choses qui ne s'expliquent pas en regardant simplement le code d'une application. En plus de connaître les éléments de base du langage de programmation lui-même (syntaxe et sémantique), vous devez connaître les conventions. Si un identifiant dans Java commence par une majuscule, c'est un type. Il y a beaucoup de ces conventions que vous devez connaître.
La convention sur la configuration consiste à réduire la quantité de décisions que le programmeur doit prendre à propos des choses. Pour certaines choses, c'est évident - personne n'envisagerait d'avoir un langage où la capitalisation des types est quelque chose que vous devez déclarer en haut de votre programme - mais pour d'autres choses ce n'est pas si évident.
Équilibrer la convention et la configuration est une tâche difficile. Trop de convention peut rendre le code confus (prenez les variables implicites de Perl, par exemple). Trop de liberté du côté du programmeur peut rendre les systèmes difficiles à comprendre, car les connaissances acquises d'un système sont rarement utiles lors de l'étude d'un autre.
Un bon exemple de l'endroit où la convention aide le programmeur est lors de l'écriture de plugins Eclipse. Lorsque je regarde un plugin que je n'ai jamais vu, je sais immédiatement beaucoup de choses à ce sujet. La liste des dépendances est dans MANIFEST.MF, les points d'extension sont dans plugin.xml, le code source est sous "src", et ainsi de suite. Si ces choses devaient être définies par le programmeur, chaque plugin Eclipse serait différent et la navigation dans le code serait beaucoup plus difficile.
A donné +1 à @JesperE et aime ajouter quelque chose:
est-ce qu'il viole certains principes de programmation
Oui, "la convention sur la configuration" viole le principe "explicite vaut mieux qu'implicite" (jetez un œil, par exemple, à "Zen-Of-Python" ).
D'un autre côté, la "configuration par rapport à la convention" opposée a tendance à violer "Simple est mieux que complexe", et pire, elle viole le principe DRY d'une manière subtile, car vous devez répéter les noms utilisés dans votre code également dans votre configuration.
Une partie de la "convention sur la configuration" se résume à des valeurs par défaut raisonnables. Vous ne devriez avoir qu'à configurer quelque chose pour l'utiliser à des fins non standard. Je dois comparer Struts à Rails ici. Dans Rails, vous devez mettre vos "actions/écrans" dans un dossier et ensuite ils fonctionnent. Dans Struts, vous devez toujours les mettre dans un dossier, mais vous devez également proposer un nom d'action ET un fichier JSP ET un nom de formulaire ET un bean de formulaire ET spécifier comment ces trois choses fonctionnent ensemble dans Struts-config.xml ET spécifier que le formulaire appartient à la demande (RESTful). Si cela ne suffit pas, le mappage formulaire/formulaire-bean a sa propre section dans Struts-config qui est ensuite mappée indépendamment à la section action dans le même fichier et tout repose sur des chaînes manuscrites dans le fichier JSP afin de fonctionner correctement. Pour chaque écran, c'est au moins 6 choses que vous ne devriez pas avoir à faire et autant d'occasions de faire une erreur. Je pense que vous pouvez définir la plupart ou la totalité de ces choses manuellement dans Rails si vous en avez besoin, mais 2/3 du temps de développement de Struts est consacré à la construction et au maintien de couches de complexité inutiles.
En toute honnêteté, Struts 1 a été conçu lorsque les gens portaient des applications entre le bureau et le Web. La flexibilité que Struts a intégrée le rend adapté à tout Rails fait, plus tout ce dont une application de bureau aurait besoin. Malheureusement, la montagne de configuration qui permet cette flexibilité est une énorme boule et chaîne pour quelqu'un qui a juste besoin d'écrire une application Web ou simplement une application de bureau.
J'ai travaillé quelque part où ils ont franchi la prochaine étape et argumenté, "Configuration over Code" mais ayant vu cela pris à son extrême logique, le résultat est que la configuration devient un nouveau langage de codage. C'était un jeu Shell où la complexité était contournée sans être apprivoisée de manière significative. Et cela m'a permis d'apprécier tous les contrôles de type et autres filets de sécurité dont dispose un langage de programmation bien conçu. Un format de fichier de configuration à moitié cuit qui explose sans message d'erreur si vous ajoutez un espace ou une apostrophe n'est PAS une amélioration par rapport à un langage de programmation de qualité qui a des suites d'outils d'édition et un compilateur de qualité écrit pour cela.
Je ne peux pas imaginer que le fait d'avoir des valeurs par défaut sensées viole les principes théoriques de l'extensibilité et de la modularité. Un programmeur Ruby/Rails préfèrerait plus tôt avoir un poker chaud à l'esprit que de passer à un framework comme Struts 1 où toutes les configurations sont faites explicitement dans plusieurs fichiers XML. Je ne discute pas Rails vs Struts EN GÉNÉRAL, mais cette convention peut être un énorme gain de productivité. Ces deux technologies sont la comparaison la plus extrême dans le monde réel que j'ai rencontrée.
Si vous travaillez dans Java du tout, consultez Joshua Bloch, "Effective Java", Item 2: "Considérez un constructeur face à de nombreux paramètres de constructeur" pp. 11-16. Pour la plupart des applications , certains paramètres (configuration) sont requis et certains sont facultatifs. L'idée de base est de ne demander que la configuration nécessaire et de faire en sorte que l'utilisateur (qui pourrait être un autre programme) spécifie des options supplémentaires si nécessaire. J'ai nettoyé un tas de code avec ce modèle il y a un mois et il scintille positivement.
En d'autres termes, la fonctionnalité de l'application n'est pas complètement expliquée par son propre code, mais aussi par la documentation du framework.
La fonctionnalité d'une application qui utilise un framework est toujours dépend du framework, la convention sur la configuration ne fait aucune différence à cet égard.
D'après mon expérience, la convention sur la configuration rend non seulement le code plus lisible, mais elle réduit également la possibilité d'introduire des bogues subtils (en particulier les bugs copier-coller).
Par exemple, supposons que dans certains framework A, l'événement FooBar
déclenche un appel à handleFooBar
. Dans un autre framework B, cette corrélation est configurée quelque part dans un fichier XML.
Donc, en A, c'est simplement
handleFooBar() {
...
}
et sauf si vous avez mal orthographié FooBar, il sera appelé chaque fois que FooBar se produit.
En B, c'est encore
handleFooBar() {
...
}
mais aussi
<eventconfiguration>
<event>
<type>FooBar</type>
<handler>handleFooBar</handler>
</event>
</eventconfiguration>
Avec des centaines de choses à configurer de cette façon, il est trop facile de créer accidentellement un bug subtil comme
<eventconfiguration>
<event>
<type>BarFoo</type>
<handler>handleFooBar</handler>
</event>
</eventconfiguration>
car après le copier-coller, nous n'avons changé que <type>
mais j'ai oublié de changer <handler>
.
Étant donné que ces fichiers de configuration sont volumineux et monotones, il est moins probable que quelqu'un trouve le bogue en relisant qu'il trouverait un bogue similaire dans le code de programme réel.