web-dev-qa-db-fra.com

Génération de code source automatique - bonne idée ou cauchemar potentiel?

En réponse à ma question concernant Java génération de code source , j'ai reçu cette réponse Averver moi des problèmes de maintenance potentiels:

  1. mélanger le code généré automatiquement pose toujours un risque de la modifier à l'avenir pour modifier un petit comportement. C'est juste la question de la prochaine construction, lorsque ces changements seront perdus.
  2. vous devrez utiliser uniquement sur les commentaires sur la source générée automatiquement pour empêcher les développeurs de le faire.
  3. contrôle de la version - permet de dire que vous mettez à jour le modèle de SOMEMETHOD (), la version de votre fichier source sera désormais mise à jour, même si les mises à jour de la source sont générées automatiquement. Vous verrez une histoire redondante.

Son alternative proposée consiste à améliorer les cours au moment de l'exécution à l'aide de la génération byTecode.

Ma pensée était que l'injection de code généré dans les fichiers de code source existants renforcerait la maintenabilité, car cela rend évident ce qui se passe au lieu d'effectuer des opérations dans les coulisses.

Devrais-je:

  1. créez un outil pour ajouter du code généré au code source existant; ou

  2. augmenter les classes à l'aide de la génération de bytecode au moment de l'exécution?

Quelle a été votre expérience avec l'une de ces approches?

13
Tony the Pony

J'ai fait une taille moyenne Java Projet (Ca. 300 classes) avec des modules multiples Maven avec mes classes de domaine générées automatiquement (Ca. 100 classes) d'un DSL effectué avec le projet superbe Eclipse xtext et je le referais :)

Ici, je vais donner des allusions comment je (jusqu'à aujourd'hui) viennent avec succès dans les pierres de cuméro de cumulie mentionnées:

Étant donné que mon projet était construit avec Maven, j'ai utilisé le moyen maven pour gérer le code généré automatiquement, cela signifie que même mon projet XTEXT DSL et mon projet de générateur est géré par Maven et à toutes les constructions complètes, je crée tout le code généré nouveau (comme cela devrait être). Voir: Construire des projets XText avec Maven Tycho . Donc, dans mon projet, je n'ai que de faire un "paquet maven".

J'ai divisé mon code généré et ma main dactylographié par héritage (je n'aime pas la manière C # pour couvrir une classe dans plusieurs fichiers):

/* Generated code, will not be in revision control */
abstract class AbstractFoo {
    //getters and setters
    //collection accessors
    //helper methods like toString equals hashCode
}

/* Generated one time, will be in revision control */
class Foo extends AbstractFoo{
    //business logic if needed
}

Avec un projet de générateur XTEXT, il est possible de définir des fichiers qui ne doivent être créés qu'une fois, de sorte que mes classes de béton que j'ai créées seulement une fois et conservées alors dans mon repo git. La classe de béton générée n'est rien de plus qu'une doublure pour que vous puissiez utiliser la classe même si vous ne l'ajoutez aucune méthode.

Pour les deux modèles (abstrait et béton), j'ai créé deux modèles de classe de test une pour la classe abstraite et une pour le béton, mais la classe de test en béton est à nouveau simplement générée une fois et une double doublure.

Dans mon module Maven où le code généré est situé, j'ai utilisé cette mise en page (presque les conventions Maven):

myproject/src/main/Java -> concrete generated classes, one time
myproject/src/test/Java -> generated tests, one time
myproject/target/generated-sources/mydsl -> abstract generated classes, always
myproject/target/generated-sources/mydsltests -> auto generated tests, always

Ainsi, lorsque je modifie le modèle, seul le modèle du groupe de générateurs XTEXT va changer dans mon contrôle de révision, car je n'inclut pas les sources (toujours) générées.

Je vous suggère donc de donner à Eclipse Xtext un essai, lorsque vous commencez avec les exemples de projets, vous aurez quelque chose de prototypish en moins d'une heure.

15
moritz

Je ne voudrais pas que cette approche un peu. Trop de mystère à mon goût.

Je préférerais les aspects ou les décorateurs, car vous devez les écrire au lieu de les générer et vous définissez clairement ce que vous faites lorsque vous les tiens.

7
duffymo

De ce que j'ai vu, la génération de code source fonctionne mieux si:

  1. Vous n'avez aucune raison de modifier le code de la classe une fois qu'il a été généré, ou
  2. Vous n'aurez aucune raison de ré-générer le code d'une classe une fois que vous l'avez modifiée (approche d'échafaudage), ou
  3. Vous travaillez dans une langue comme C #, ce qui vous permet de rendre les classes parcourez plusieurs fichiers. (Vous pouvez avoir un fichier avec un code généré automatiquement et un autre avec vos contributions), ou

Basé sur votre question, je suppose que rien d'entre eux n'est probablement vrai. Bien que je n'ai pas personnellement fait de génération de bytecode, j'ai remarqué que certains outils bien utilisés comme GWT ont choisi cette approche, il est donc probablement préférable.

Cependant, je demanderais à un collègue d'écouter ce que vous essayez finalement d'accomplir et de voir s'il n'y a pas de meilleur moyen d'utiliser plus de standard Java pratiques.

5
StriplingWarrior

Vous pouvez avoir votre processus de construction générer le code, le jar en haut et l'inclure sur la classe de classe de votre projet dépendant. Cela empêchera le problème avec la modification de la source générée, vous n'avez pas besoin de la version du pot généré uniquement des métadonnées qu'il a été construite.

C'était l'approche que j'ai utilisée dans le passé avec des outils tels que Xmlbeans et cela fonctionnait plutôt bien.

4
nsfyn55

Le Cadre de modélisation Eclipse fait vraiment superbe génération de code, mais est compliqué pour se mettre à croître. Il est apparemment capable de permettre des ajouts de code d'utilisateur dans le code de modèle sans renvoyer ces modifications à chaque fois que le modèle est régénéré. En outre, l'éditeur d'interface utilisateur Matise dans NetBeans effectue toute la génération de l'interface utilisateur et la maintient à jour.

2
Chris Dennett

En fait, dans les formes gérées C++, vous avez des codes automatiques et manuels mélangés ensemble dans le fichier .h. Le code automatique est mis à jour chaque fois que vous ouvrez le formulaire en mode concepteur, modifiez quelque chose et enregistrez. Fonctionne tout aussi bien que le code généré dans un fichier séparé.

1
AareP