2009-04-22 8 views
2

J'ai une source de données plutôt particulière que je dois travailler (une interface à une application de comptabilité en fait). Bien que ce soit assez puissant, je dois passer par de nombreuses étapes pour obtenir les données que je veux en retirer. Par exemple, si je veux obtenir le contenu d'une table et spécifier les colonnes qu'elle doit renvoyer, je dois parcourir la collection .Columns et appeler .SetVisible() à ceux que je veux.DSL vs appels de méthode: avantages et inconvénients

Actuellement, nous avons une méthode qui contourne cela et nous permet de spécifier les choses de manière plus simple, mais la liste des paramètres de cette fonction est en croissance rapide, et la plupart du temps nous ne devons en spécifier que quelques-uns quand on l'appelle. En bref - c'est une solution inflexible.

La première solution qui vient à mon esprit était quelque chose comme ceci:

DataTable result = DataSourceWrapper.StartQuery("TableName") 
    .SetVisibleColumns("Col1", "Col2", "Col3") 
    .SetCriteria("CriteriaName", "Param1Name", CriteriaParam1, "Param2Name", CriteriaParam2) 
    .SetFilter("Col4 = ? AND Col5 = ?", FilterParam1, FilterParam2) 
    .SetReportParams("Param1Name", ReportParam1, "Param2Name", ReportParam2) 
    .Execute(); 

critères, filtres et ReportParams sont des choses spécifiques à l'application et je ne vais pas en discuter ici. Mais l'idée générale est comme ça. Il est pratiquement analogue à l'appel d'une méthode, sauf que vous pouvez choisir les paramètres à spécifier (en appelant des méthodes spécifiques) et avoir un peu plus d'assistance IntelliSense. Et vous pouvez également jouer avec l'ordre des appels de méthode. Notez que SetFilter() a une expression à analyser. C'est une autre chose que le DataSource rend difficile - il peut traiter des expressions assez bien, mais vous devez les passer comme un arbre d'objets spéciaux, ce qui est encore assez long à écrire. Dans un previous question j'ai demandé de l'aide sur l'analyse de telles expressions. La méthode wrapper actuelle a un analyseur d'expression homebrew, qui peut analyser des expressions simples, mais j'ai pensé à rendre leur support plus complet.

Dans cette question, le projet Irony a été suggéré. Après avoir vérifié, j'ai décidé qu'il était en effet adapté à ce besoin. Mais au bout d'un moment, il m'est apparu que c'était encore plus puissant que ça. Pourquoi ne pas créer mon propre langage de requête adapté à cette tâche? Ce qui précède ressemblerait alors à:

DataTable result = DataSourceWrapper.Query(@" 
    SELECT Col1, Col2, Col3 
    FROM TableName 
    WITH CRITERIA CriteriaName(Param1Name={0}, Param2Name={1}) 
    WITH REPORTPARAMS (Param1Name={2}, Param2Name={3} 
    WHERE Col4 = {4} AND Col5 = {5}", 
    CriteriaParam1, CriteriaParam2, 
    ReportParam1, ReportParam2, 
    FilterParam1, FilterParam2 
); 

Mais ... ne serait-ce pas une surcharge? Quels sont les avantages et les inconvénients de l'une ou l'autre approche? Ce que je vois est:

DSL Pro:

  • requête plus concis;

Méthodes Pro:

  • Plus de soutien IntelliSense;
  • Les noms de méthodes/noms de paramètres (et commentaires) ont moins besoin de documentation (DSL devra être documenté de manière approfondie);
  • Peut-être plus rapide à créer? Je n'ai jamais créé mon propre DSL, donc je ne sais pas combien de travail c'est. Ironie semble prendre beaucoup du fardeau de mes épaules, mais combien reste-t-il encore là?

Ajouté: Pour clarifier, les deux approches ne seront utilisées que par les codeurs. Les personnes externes et les analystes d'affaires ne l'utiliseront pas.

Répondre

2

Vous devez faire attention à ce que vous appelez un DSL. Voir Martin Fowler's Bliki post on DSL. Votre exemple de chaînage de méthode est très proche d'un DSL interne. Modifier légèrement et il est:

DataTable result = DataSourceWrapper.Query("TableName") 
    .With(new Columns("Col1", "Col2", "Col3")) 
    .Where(new AndCritera("CriteriaName", 
     new Criterion("Param1Name", CriteriaParam1), 
     new Criterion("Param2Name", CriteriaParam2)) 
    .Filter(
     new Filter("Col4").Equals(FilterParam1), 
     new Filter("Col5").Equals(FilterParam2)) 
    .With(
     new ReportParam("Param1Name", ReportParam1), 
     new ReportParam("Param2Name", ReportParam2)); 

Cela étant dit, cela est encore très dans le domaine C#, et seuls les programmeurs pourront écrire ces requêtes. Si vos exigences vous poussent à mettre des requêtes à la disposition des non-programmeurs, vous pouvez envisager de créer un DSL externe comme indiqué dans le deuxième exemple.

+0

Non, ce ne sera que pour un usage interne de nous, les programmeurs. Et, oui - c'est exactement ce que je veux dire. Je suis si proche d'une DSL réelle, que la prochaine étape serait de le faire. Le but de tout cela est de rendre le code plus facile à écrire, donc DSL gagne un peu dans cet aspect (c'est même plus court que ce que vous avez écrit ici), mais ce qui m'inquiète, c'est combien de temps cela me prendra pour le créer. Et peut-être y a-t-il d'autres obstacles que je ne connais pas. –

+0

Je dirais qu'il n'y a aucune valeur ajoutée dans la création d'un DSL entièrement externe si les seuls consommateurs seront des programmeurs C#. Cela finit par être une perte de temps dans ce cas puisque les programmeurs peuvent facilement interagir avec votre DSL interne en utilisant Visual Studio. –

0

J'opterais pour l'approche DSL.

raisons: 1, il est plus proche des experts du domaine, de son expérience personnelle, les baccalauréats comme quelque chose dans les formes DSL, il brise la barrière de communication entre les gens d'esprit d'entreprise et les développeurs, et facilite la rédaction de spécifications techniques beaucoup plus facile 2 en utilisant un outil comme Irony, votre DSL sera bien défini et un bon candidat pour le développement piloté par les tests 3 implémenter DSL nécessite un peu d'apprentissage initial sur les développeurs (j'ai utilisé javacc, qui est encore moins convivial que Irony) mais Une fois que vous avez compris les idées, cela devient facile, et votre code devient assez générique parce que vous déchargez la logique dans DSL.

Questions connexes