【问题标题】:What is the programming rationale for logic-less templates vs. more capabilities in the template language?无逻辑模板与模板语言中更多功能的编程原理是什么?
【发布时间】:2014-09-19 17:27:43
【问题描述】:

无逻辑模板(如小胡子/车把)的编程原理是什么?为什么故意限制模板语言的功能被这些无逻辑模板库的制造商和用户认为是一种良好且理想的设计模式?

我最近在一个小项目中使用 node.js 和车把,我发现我经常因车把模板中缺乏简单的逻辑而受阻。

在我放弃手把模板引擎以寻找具有更强大逻辑功能的模板引擎之前,我想了解使用无逻辑模板语言背后的编程原理。

我应该澄清一下,我并不是在征求人们对哪种模板语言更好的意见。我在问人们设计、构建和使用无逻辑模板的客观原因是什么。


这是一个相当简单的示例,说明我希望模板能够自行处理,但我不知道在把手中如何处理,所以我不明白为什么它被认为是“无逻辑”的理想特性" 模板本身无法处理如此简单的 UI 演示。由于有许多无逻辑的模板选择,我假设有一些我想了解的有用原因。

我有两个来自可能应用程序状态的变量传递给模板:

fanOn       // boolean: true or false
fanControl  // three states: "on", "off", "auto"

fanOn 代表我正在控制的某些风扇的当前状态 fanControl 描述了风扇处于哪种控制模式。“开”表示它们是手动打开的,并将保持这种状态,直到另行通知。 “关闭”表示它们被手动关闭并将保持这种状态,直到另行通知。 “自动”表示它们处于自动恒温/软件控制之下。

如果风扇打开,我想显示一个按钮来手动关闭它们。

如果风扇关闭,我想显示一个按钮来手动打开它们。

如果 fanControl 设置打开或关闭,我想显示一个按钮将其设置回自动。

因此,总是有一个“打开”或“关闭”按钮,如果它不处于“自动”模式,则有一个“设置回自动”按钮。

这里没有业务逻辑,只是根据当前状态构建适当的表示。

以下是我在该主题上找到的各种参考资料(其中包含观点和事实的组合 - 读者必须弄清楚哪个是哪个):

【问题讨论】:

  • 这是业务逻辑:您有 2 个 UI 显示,一个在自动模式下,一个在非自动模式下。控制器应在两者之间进行选择。选择不是视图的工作。视图应该只是将内容绘制到屏幕上。
  • 请注意,如果两个模板彼此共享很多东西,大多数模板引擎都具有允许您重构它们的功能。
  • @slebetman - 我认为模板的工作是决定如何准确呈现 UI。是否应该使用按钮、单选组、下拉菜单等...?我看不出为什么 javascript 收集页面将代表的数据需要参与按钮、单选组或下拉列表。就我而言,这是模板的工作来保持适当的设计。是的,Handlebars 模板确实有“部分”,其中包含可在多个地方使用的可重用 HTML 片段。我在适当的地方使用它们——尽管我认为这与这里无关。
  • 去阅读cs.usfca.edu/~parrt/papers/mvc.templates.pdf 以获得关于为什么无逻辑模板是一件好事的优秀学术处理。这一切都与模型视图分离有关。
  • @jfriend00:阅读 MVC 设计模式。 MVC 来自 smalltalk 和 veiw 层,没有模板,而是 smalltalk 代码。策略仍然是只在视图中调用 UI 函数,让控制器来做所有的决定。

标签: node.js handlebars.js mustache


【解决方案1】:

人们倾向于在模板中包含业务逻辑,尤其是对于没有经验的程序员。这通常被认为是不好的做法和反模式。业务逻辑属于模型层,不应该与表示/视图层有任何关系。

极端情况下,您最终会使用 PHP - 其中 100% 的所有代码、业务逻辑、控制器粘合和视图都嵌入在 HTML 中。

为了阻止这种情况,开发了无逻辑模板,这样初级开发人员就不会意外地将业务逻辑轻松地包含在视图层中。

对于真正良好的关注点分离(单一职责)检查值以决定在屏幕上打印什么不是视图层的责任。它应该在控制器中完成。然而,有时它真的不应该是控制器的工作(例如,当使用由原始元素组成的复合 UI 元素时,检查可能是实现细节的一部分)。对于这些用例,模板库通常很有用,以提供诸如辅助方法之类的变通方法。但这样的用例应该很少见。

如果您一直不得不编写辅助方法,那可能是您不习惯将控制器逻辑与表示逻辑分开。因此,一些更极端的无逻辑模板语言(例如 Google 的 ctemplate)甚至不提供此类解决方法(请注意,ctemplate 早于许多较新的无逻辑模板语言)。

无逻辑语言的新发展更加极端——无模板语言。如果模板语言根本没有语言,而您只需传递正确的 JSON 数据(或其他结构化数据),模板引擎就会找到具有正确 id 或类名的匹配 HTML 元素来注入值。

【讨论】:

  • 如果您提供了一些代码,也许有人可以为您的问题提供更简洁的解决方案。看似限制的结果是由对潜在问题有深刻理解的人做出的明智决定的结果。
  • @PeterVC - 我要求解释这种深刻的理解,因为不允许在表示层做出任何有用的决定对我来说似乎比它有帮助的限制更多,所以我正在尝试了解为什么这群人的想法不同。这也可能告诉我应该如何构建我的代码以及为什么。我将在今天晚些时候提供一个具体的例子(现在开始)——尽管我在对这篇文章的第一条评论中确实描述了一个问题(在高层次上)。
  • 误解源于将“模板”与“表示层”混为一谈的(常见)问题。 Web 框架和语言往往会出错 :) 真正的 MVC 视图不是由模板文件构成的,它是由代码构成的。 Mustache 和其他无逻辑模板引擎强制执行这种区别。决策不能在模板中做出。模板只是一个由其他地方的视图代码填充的字符串。如果你从这个角度来看,Mustache 的局限性是可行的。如果您尝试完全不使用 View 代码而不是将代码移动到 View 层,那么它不会。
  • @PeterVC - 我在我的问题中添加了一个具体示例。
  • 但那些业务逻辑。它们是简单的逻辑,但仍然是逻辑。您的模板会改为询问“我应该显示此按钮吗?”和“我应该显示另一个按钮吗?”做出这些决定所需的逻辑属于代码,可以在其中进行分析、测试和推理。 kneath 在这里稍微介绍了它的力量:warpspire.com/posts/mustache-style-erb
【解决方案2】:

在研究了一堆其他模板语言之后,似乎基本上有三种思想流派,你真的必须决定哪一种最符合你的开发理念、团队情况和项目需求。

选项 #1: 模板中包含成熟的编程语言(例如 PHP)。

选项 #2: 模板没有逻辑(例如 Mustache/Handlebars)。

选项 #3: 模板有一些能力来做出以演示为中心的逻辑决策(例如 Dust)。

PHP 模型存在并且有效。如果没有适当的纪律,演示文稿和业务逻辑可能会非常交织在一起,造成无法测试的混乱。这并不意味着良好的纪律和适当的技术不能导致干净的实施,但不正确的做法也很容易自取其辱。

也许作为对由此造成的混乱以及随后的一些争论的反应,无逻辑模板的概念出现了。零业务逻辑可以放入无逻辑模板中。但是,由于模板中没有逻辑,因此必须在某处有另一层代码来做出表示逻辑决策并预处理发送到模板的数据,以便它与所选的 UI 设计完全一致。这需要一个单独的地方用于表示逻辑代码。如果没有适当的纪律或理解,此代码会与业务逻辑混杂在一起,并且通常必须修改此代码以对模板中的 UI 设计进行相当简单的更改。没有纪律的案例可能不像选项 #1 那样混乱,但仍然有些人认为这也不理想 - 其他人似乎喜欢它。

第三个选项是模板尝试公开足够的逻辑,以根据屏幕大小、数据状态、选择哪个单选按钮、显示哪些按钮等做出基于演示的决策......但仍然保留与主应用程序中的任何业务逻辑分开。此外,这可以让具有不同技能的人(例如 UI 设计师)更全面地控制演示文稿,而无需涉及主服务器端应用程序中的 javascript 程序员。

与许多工具一样,人们可以争论每种方法的优缺点,并且没有绝对正确或错误的答案。

在寻找更符合选项 #3 的模板时,我遇到了Dust(LinkedIn 使用)和WalrusNunjucks,这些简介在他们的文档中帮助描述了他们的目标选项#3:

来自Walrus

视图逻辑不同于业务逻辑(没关系!)。在现代 Web 应用程序中,通常会涉及大量的表示逻辑。此逻辑不属于您的应用程序代码、主干模型或除表示层之外的任何其他地方。模板语言是放置这个的好地方。

还有,来自Dust

模板中的逻辑

具有逻辑的模板与“无逻辑”模板是模板语言设计者和用户之间激烈争论的话题。灰尘通过采取“不那么逻辑”的立场跨越了鸿沟。我们都知道真正的业务逻辑不属于表示层,但是对于简单的面向表示的事情,比如为表格中的交替行着色或在下拉列表中标记选定的选项呢?要求控制器/业务逻辑代码将这些计算为简单的布尔值以减少演示模板中的逻辑似乎同样错误。这条路线只会导致业务层代码被面向表示的逻辑污染。 Dust 提供了一些简单的逻辑机制,并相信您在最小化模板中的逻辑以仅处理面向演示的决策方面是明智的。也就是说,让我们看看 Dust 让你有逻辑的方式。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-30
    • 1970-01-01
    • 2016-07-29
    • 1970-01-01
    • 1970-01-01
    • 2010-10-17
    • 1970-01-01
    相关资源
    最近更新 更多