web-dev-qa-db-fra.com

Quel est l'avantage du modèle sans logique (comme la moustache)?

Récemment, je suis tombé sur moustache qui est censé être modèle sans logique.

Cependant, rien n’explique pourquoi il est conçu de manière sans logique. Dans un autre mot, quel est l'avantage du modèle sans logique?

95
Morgan Cheng

En d'autres termes, cela vous empêche de vous tirer une balle dans le pied. À l’époque des JSP, il était très courant d’avoir des fichiers JSP saupoudrés de code Java, ce qui rendait beaucoup plus difficile le refactoring, puisque votre code était dispersé.

Si vous empêchez la logique dans les modèles de par leur conception (comme le fait la moustache), vous serez obligé de mettre la logique ailleurs, pour que vos modèles se retrouvent sans encombrement.

Un autre avantage est que vous êtes obligé de penser en termes de séparation des problèmes: votre contrôleur ou votre code logique devra traiter les données masser avant d’envoyer des données à l’UI. Si par la suite vous changez de modèle pour un autre (disons que vous commencez à utiliser un moteur de gabarit différent), la transition sera facile car il vous suffit d'implémenter les détails de l'interface utilisateur (puisqu'il n'y a pas de logique dans le modèle, n'oubliez pas).

99
Miguel Ping

J'ai l'impression d'être presque seul à mon avis, mais je suis fermement dans le camp opposé. Je ne crois pas que le mélange possible de la logique métier dans vos modèles soit une raison suffisante pour ne pas utiliser toute la puissance de votre langage de programmation.

L'argument habituel des modèles sans logique est que si vous avez un accès complet à votre langage de programmation, vous pouvez mélanger une logique qui n'a pas sa place dans un modèle. Je trouve que cela revient à penser que vous devriez utiliser une cuillère pour trancher de la viande, car vous pourriez vous couper si vous utilisez un couteau. C’est très vrai, et pourtant vous serez beaucoup plus productif si vous utilisez ce dernier, quoique avec précaution.

Par exemple, considérons l'extrait de modèle suivant à l'aide de moustache :

{{name}}:
<ul>
  {{#items}}
    <li>{{.}}</li>
  {{/items}}
</ul>

Je peux comprendre cela, mais je trouve que le texte suivant (avec underscore ) est beaucoup plus simple et direct:

<%- name %>:
<ul>
<% _.each(items, function(i){ %>
  <li><%- i %></li>
<% }); %>
</ul>

Cela dit, je comprends que les modèles sans logique ont des avantages (par exemple, ils peuvent être utilisés avec plusieurs langages de programmation sans modification). Je pense que ces autres avantages sont très importants. Je ne pense tout simplement pas que leur nature sans logique est l'une d'entre elles.

64
brad

Moustache est sans logique?

N'est-ce pas:

{{#x}}
  foo
{{/x}}
{{^x}}
  bar
{{/x}}

Assez semblable à ceci?

if x
  "foo"
else
  "bar"
end

Et est-ce que que n'est pas assez similaire à (lire: presque une définition de) la logique de présentation?

25
pje

Un modèle sans logique est un modèle qui contient des trous à combler, et non pas comment vous les remplissez. La logique est placée ailleurs et directement mappée sur le modèle. Cette séparation des préoccupations est idéale car le modèle peut donc être facilement construit avec une logique différente, voire avec un langage de programmation différent.

Du manuel moustache :

Nous l'appelons "sans logique" car il y a ne sont pas des déclarations if, else clauses ou pour les boucles. Au lieu de cela, il n'y a que Mots clés. Certaines balises sont remplacées par un valeur, certains rien, et d'autres un série de valeurs. Ce document explique les différents types de Étiquettes de moustache.

13
Jeremy

Cela rend vos modèles plus propres et vous oblige à conserver la logique dans un endroit où elle peut être testée correctement.

11
blockhead

Le revers de la médaille est que, dans une tentative désespérée de garder la logique métier en dehors de la présentation, vous finissez par mettre beaucoup de logique de présentation dans le modèle. Un exemple courant pourrait être que vous vouliez mettre des classes "impaires" et "paires" sur des lignes alternées dans une table, ce qui pourrait être fait avec un simple opérateur modulo dans le modèle de vue. Mais si votre modèle de vue ne vous permet pas de le faire, alors dans vos données de modèle, vous devez non seulement stocker la ligne impaire ou paire, mais en fonction des limites de votre moteur de modèle, vous devrez peut-être même polluer votre modèle. avec les noms des classes CSS actuelles. Les vues doivent être séparées des modèles, à point. Mais les modèles doivent également être agnostiques pour View, et c'est ce que beaucoup de ces moteurs de modèles "sans logique" vous font oublier. La logique va aux deux endroits, mais vous devez être judicieux sur ce que la logique en fait décide correctement où elle va. S'agit-il d'un problème de présentation ou d'un problème d'entreprise/de données? Dans un effort pour obtenir des vues à 100% vierges, la pollution se pose dans un autre endroit moins visible mais tout aussi inapproprié.

Il y a un mouvement croissant dans la direction opposée, et espérons que les choses se centreront quelque part dans le juste milieu.

10
mattmc3

Cette conversation se passe comme lorsque les moines du moyen âge discutaient du nombre d'anges pouvant tenir à l'extrémité d'une épingle. En d'autres termes, il commence à se sentir religieux, futile et mal centré.

Le mini-rant s'ensuit (n'hésitez pas à l'ignorer): 

Si vous ne voulez pas continuer à lire, ma réponse brève au sujet ci-dessus est: Je ne suis pas d'accord avec les modèles sans logique. Je pense à cela comme une forme de programmation de l'extrémisme. :-) :-)

Maintenant mon coup de gueule continue en plein essor: :-)

Je pense que lorsque vous prenez beaucoup d'idées à l'extrême, le résultat devient ridicule. Et parfois (c’est-à-dire ce sujet) le problème est que nous prenons la "mauvaise" idée à l’extrême. 

Supprimer toute logique de la vue est "ludicroous" et la mauvaise idée. 

Reculez un instant.

La question que nous devons nous poser est la suivante: pourquoi supprimer la logique? Le concept, évidemment, est séparation des préoccupations . Conservez le traitement de la vue aussi distinct que possible de la logique applicative. Pourquoi faire ceci? Il nous permet d’échanger des vues (pour différentes plates-formes: mobile, navigateur, ordinateur de bureau, etc.) et d’échanger plus facilement le flux de contrôle, la séquence des pages, les modifications de validation, les modifications de modèle, les accès de sécurité, etc. supprimé des vues (notamment les vues Web), il rend les vues beaucoup plus lisibles et donc plus faciles à gérer. Je comprends cela et je suis d’accord avec ça.

Cependant, l'accent devrait être mis sur la séparation des préoccupations. Pas de vues 100% sans logique. La logique dans les vues doit être liée à la manière de rendre le "modèle". En ce qui me concerne, la logique dans les vues va parfaitement. Vous pouvez avoir une logique de vue qui n'est pas une logique d'entreprise.

Oui, à l'époque où nous écrivions des pages JSP, PHP ou ASP avec peu ou pas de séparation entre la logique du code et la logique d'affichage, la maintenance de ces applications Web était un véritable cauchemar. Croyez-moi, je sais, j'ai créé puis maintenu certaines de ces monstruosités. C'est pendant cette phase de maintenance que j'ai vraiment compris (viscéralement) l'erreur de mes manières et de celles de mes collègues. :-) :-)

Ainsi, l'édit d'en haut (les experts de l'industrie) est devenu, vous devez structurer vos applications Web en utilisant quelque chose comme un contrôleur de vue de face (qui est envoyé à des gestionnaires ou des actions [choisissez votre infrastructure Web]) et vos vues ne doivent pas contenir de code . Les vues deviendraient des modèles stupides.

Je suis donc généralement d’accord avec le sentiment ci-dessus, non pas pour les détails des éléments de l’édit, mais plutôt pour la motivation qui sous-tend l’édit - qui est le désir de séparer les préoccupations entre la vision et la logique d’entreprise.

Dans un projet auquel j'ai participé, nous avons essayé de suivre l'idée d'une vision sans logique à l'extrême ridicule. Nous avions un moteur de gabarit développé en interne qui nous permettait de rendre les objets de modèle au format HTML. C'était un système simple basé sur des jetons. C'était terrible pour une raison très simple. Parfois, dans une vue que nous devions décider, devrais-je afficher ce petit extrait de HTML .. ou pas .. La décision est généralement basée sur une valeur du modèle. Quand vous n'avez absolument aucune logique dans la vue, comment faites-vous cela? Eh bien, vous ne pouvez pas. J'ai eu d'importants arguments avec notre architecte à ce sujet. Les rédacteurs de HTML qui ont écrit notre point de vue étaient complètement bloqués devant cette situation et étaient très stressés, car ils ne pouvaient pas atteindre leurs objectifs autrement simples. J'ai donc introduit le concept d'une simple instruction IF dans notre moteur de templates. Je ne peux pas vous décrire le soulagement et le calme qui ont suivi. Le problème a été résolu avec un simple concept IF-Statement dans nos modèles! Soudain, notre moteur de modélisation est devenu bon.

Alors, comment sommes-nous entrés dans cette situation stressante et stupide? Nous nous sommes concentrés sur le mauvais objectif. Nous avons suivi la règle, vous ne devez avoir aucune logique dans vos vues. C'était faux. Je pense que la "règle générale" devrait être, minimiser cette quantité de logique dans vos vues. Sinon, vous pourriez autoriser par inadvertance la logique métier à se glisser dans la vue, ce qui constitue une violation de la séparation des préoccupations.

Je comprends que lorsque vous déclarez que "Vous ne devez avoir aucune logique dans les vues", il devient facile de savoir quand vous êtes un "bon" programmeur. (Si c'est votre mesure de bonté). Maintenant, essayez d'implémenter une application web de complexité moyenne même avec la règle ci-dessus. Ce n'est pas si facile à faire.

Pour moi, la règle de logique dans les points de vue n’est pas si claire et, franchement, c’est ce que je veux que ce soit.

Lorsque je vois beaucoup de logique dans les vues, je détecte une odeur de code et tente d'éliminer la majeure partie de la logique des vues - j'essaie de faire en sorte que la logique métier soit ailleurs - j'essaie de dissocier les préoccupations. Mais quand je commence à discuter avec des gens qui disent que nous devons supprimer toute logique, eh bien, pour moi, ça sent le fanatisme, car je sais que vous pouvez vous retrouver dans des situations telles que celles décrites ci-dessus.

J'en ai fini avec mon coup de gueule. :-)

À votre santé,

David

5
David Balme

Le meilleur argument que j'ai présenté pour les modèles sans logique est que vous pouvez utiliser exactement les mêmes modèles à la fois sur le client et sur le serveur. Cependant, vous n'avez pas vraiment besoin d'être sans logique, juste un qui a son propre "langage". Je suis d'accord avec les gens qui se plaignent que la moustache est une limitation inutile. Merci, mais je suis un grand garçon et je peux garder mes modèles propres sans votre aide.

Une autre option consiste simplement à rechercher une syntaxe de modèle qui utilise un langage pris en charge sur le client et le serveur, à savoir javascript sur le serveur en utilisant node.js ou vous pouvez utiliser un interpréteur js et json via quelque chose comme therubyracer.

Ensuite, vous pouvez utiliser quelque chose comme haml.js, qui est beaucoup plus propre que tous les exemples fournis jusqu'à présent et fonctionne très bien.

5
eagspoo

En une phrase: sans logique signifie que le moteur de gabarit lui-même est moins complexe et présente donc une empreinte au sol réduite et qu'il y a moins de façons de se comporter de manière inattendue.

4
Kernel James

Bien que la question soit ancienne et que la réponse soit apportée, j'aimerais ajouter 2 ¢ (ce qui peut sembler une folie, mais ce n'est pas le cas, il s'agit de limitations et lorsqu'elles deviennent inacceptables).

Le but d'un modèle est de restituer quelque chose, pas d'appliquer une logique métier. À présent, il n’ya plus qu’une différence entre ne pas pouvoir faire ce que vous devez faire dans un modèle et avoir une "logique métier". Même si j'étais vraiment positif envers Moustache et que j'essayais de l'utiliser, je ne pouvais pas faire ce dont j'avais besoin dans des cas assez simples.

Le "massage" des données (pour utiliser les mots de la réponse acceptée) peut devenir un réel problème - même les chemins les plus simples ne sont pas pris en charge (quelque chose dont l'adresse Handlebars.js). Si j'ai des données de vue et que je dois modifier cela à chaque fois que je veux effectuer un rendu, car mon moteur de gabarit est trop restrictif, cela n'aide en rien. Et cela va à l'encontre d'une partie de l'indépendance de la plate-forme que la moustache réclame pour elle-même; Je dois dupliquer la logique de massage partout.

Cela étant dit, après une certaine frustration et après avoir essayé d'autres moteurs de modèles, nous avons finalement créé notre propre (... encore un autre ...), qui utilise une syntaxe inspirée des modèles .NET Razor. Il est analysé et compilé sur le serveur et génère une fonction JS simple et autonome (en tant que module RequireJS) qui peut être appelée pour "exécuter" le modèle, en renvoyant une chaîne comme résultat. L’échantillon donné par brad ressemblerait à ceci lors de l’utilisation de notre moteur (que je trouve personnellement bien supérieur à celui de Moustache et de Underscore):

@name:
<ul>
@for (items) {
  <li>@.</li>
}
</ul>

Une autre limitation dépourvue de logique nous a frappé lors de l'appel à des partiels avec Moustache. Bien que les partiels soient pris en charge par Moustache, il n’existe aucune possibilité de personnaliser les données à transmettre en premier. Ainsi, au lieu de pouvoir créer un modèle modulaire et de réutiliser de petits blocs, je finirai par créer des modèles contenant du code répété.

Nous avons résolu ce problème en mettant en œuvre un langage de requête inspiré de XPath, appelé JPath. Fondamentalement, au lieu d’utiliser/pour traverser vers les enfants, nous utilisons des points, et non seulement les chaînes, chaîne et nombre sont prises en charge, mais également les objets et les tableaux (tout comme JSON). Le langage est sans effets secondaires (ce qui est indispensable pour les modèles) mais permet de "masser" les données selon les besoins en créant de nouveaux objets littéraux.

Supposons que nous voulions afficher une table "grille de données" avec des en-têtes personnalisables et des liens vers des actions sur les lignes, puis ajouter dynamiquement des lignes à l'aide de jQuery. Les lignes doivent donc être partielles si je ne veux pas dupliquer le code. Et c'est là que le problème commence si des informations supplémentaires, telles que les colonnes à restituer, font partie du modèle de vue, et il en va de même pour les actions de chaque ligne. Voici quelques exemples de code de travail utilisant notre modèle et notre moteur de requête:

Modèle de table:

<table>
    <thead>
        <tr>
            @for (columns) {
                <th>@title</th>
            }
            @if (actions) {
                <th>Actions</th>
            }
        </tr>
    </thead>
    <tbody>
        @for (rows) {
            @partial Row({ row: ., actions: $.actions, columns: $.columns })
        }
    </tbody>
</table>

Modèle de ligne:

<tr id="@(row.id)">
    @for (var $col in columns) {
        <td>@row.*[name()=$col.property]</td>
    }
    @if (actions) {     
        <td>
        @for (actions) {
            <button class="btn @(id)" value="@(id)">@(name)...</button>
        }
        </td>
    }
</tr>

Invocation à partir du code JS:

var html = table({
    columns: [
        { title: "Username", property: "username" },
        { title: "E-Mail", property: "email" }
    ],
    actions: [
        { id: "delete", name: "Delete" }
    ],
    rows: GetAjaxRows()
})

Il ne contient aucune logique métier, mais il est réutilisable et configurable, sans aucun effet secondaire.

3
Lucero

Je suis d’accord avec Brad: le style underscore est plus facile à comprendre. Mais je dois admettre que le sucre syntaxique risque de ne pas plaire à tout le monde. Si _.each est quelque peu déroutant, vous pouvez utiliser une boucle for traditionnelle. 

  <% for(var i = 0; i < items.length; i++) { %>
    <%= items[i] %>
  <% } %>

C'est toujours agréable si vous pouvez vous rabattre sur des constructions standard telles que for ou if. Utilisez simplement <% if() %> ou <% for() %> pendant que Mustache utilise un peu le néologisme pour if-then-else (et déroutant si vous n'avez pas lu la documentation):

{{#x}}
  foo
{{/x}}
{{^x}}
  bar
{{/x}}

Le moteur de modèles est idéal lorsque vous pouvez facilement créer des modèles imbriqués (style underscore):

<script id="items-tmpl" type="text/template">
    <ul>
        <% for(var i = 0; i < obj.items.length; i++) { %>
            <%= innerTmpl(obj.items[i]) %>
        <% } %>
    </ul>
</script>

<script id="item-tmpl" type="text/template">
    <li>
        <%= name %>
    </li>
</script>

var tmplFn = function(outerTmpl, innerTmpl) {
    return function(obj) {
        return outerTmpl({obj: obj, innerTmpl: innerTmpl});
    };
};

var tmpl = tmplFn($('#items-tmpl').html(), $('#item-tmpl').html());
var context = { items: [{name:'A',{name:'B'}}] };
tmpl(context);

Fondamentalement, vous transmettez votre tmpl interne en tant que propriété de votre contexte. Et appelez en conséquence. Sucré :)

En passant, si le moteur de modèle vous intéresse uniquement, utilisez l'implémentation de modèle autonome. C'est seulement 900 caractères une fois minifiés (4 longues lignes):

https://Gist.github.com/marlun78/2701678

1
roland

Voici 3 façons de rendre une liste, avec le nombre de caractères. Tous, sauf le premier et le plus court, sont écrits dans des langages de modélisation sans logique.

CoffeeScript (avec café réactif générateur DSL) - 37 caractères

"#{name}"
ul items.map (i) ->
  li i

Knockout - 100 caractères

<span data-bind="value: name"/>
<ul data-bind="foreach: items">
   <li data-bind="value: i"/>
</ul>

Guidon/Moustache - 66 caractères

{{name}}:
<ul>
  {{#items}}
    <li>{{.}}</li>
  {{/items}}
</ul>

Trait de soulignement - 87 caractères

<%- name %>:
<ul>
<% _.each(items, function(i){ %>
  <li><%- i %></li>
<% }); %>
</ul>

Je suppose que la promesse de modèles sans logique était que les personnes ayant des compétences plus étendues seraient capables de gérer des modèles sans logique sans se tirer une balle dans le pied. Cependant, ce que vous voyez dans les exemples ci-dessus, c'est que lorsque vous ajoutez un langage de logique minimale au balisage basé sur des chaînes, le résultat est plus complexe, pas moins. En outre, vous ressemblez à du PHP old-school.

Clairement, je ne m'oppose pas à ce que la "logique métier" (calcul étendu) soit exclue des modèles. Mais je pense qu'en leur donnant un pseudo-langage pour la logique d'affichage au lieu d'un langage de première classe, le prix est payé. Pas simplement plus de dactylographie, mais un mélange odieux de changement de contexte, il faut que quelqu'un le lise. 

En conclusion, je ne vois pas la logique des modèles sans logique, alors je dirais que leur avantage est nul pour moi, mais je respecte le fait que beaucoup de gens de la communauté voient les choses différemment :)

1
Dean Radcliffe

Les principaux avantages de l'utilisation de modèles sans logique sont les suivants:

  • Strictement applique la séparation modèle-vue, voir le présent document pour plus de détails (hautement recommandé)
  • Très facile à comprendre et à utiliser, car aucune logique de programmation (et connaissance!) N'est nécessaire et la syntaxe est minimale
  • (Moustache particulière) hautement portable et indépendant du langage, peut être utilisé sans modification dans presque tous les environnements de programmation
0
rmuller