Stephan Schmidt 表示,人们无法理解业务逻辑和UI逻辑之间的区别
人们大多数时候在模板中使用业务逻辑,无论是JSP、Velocity还是Rails。他们混淆了业务逻辑和UI逻辑。这两者是完全不同的事情。
Stephan 举了一个应该避免的例子,如下代码
<c:if test="${user.loggedIn && user.bookedProducts}"> // show menu </c:if>
好吧,我可以算是那些不理解这种差别的人之一。我看不出上面的代码表达式是实现了 业务
逻辑而不是 用户界面
逻辑。实际上,在我看来,区分构成 /用户界面/ 的确切边界在一般情况下更多的是艺术而非科学。
在这个特定的例子中,似乎是这样的&&Stephan 反对。如果我能正确理解他的话,他不会有任何问题
<c:if test="${user.loggedIn}"> // show menu </c:if>
或者这个
<c:if test="${user.bookedProducts}"> // show menu </c:if>
然而,我认为仅仅使用连接词在先验上是不够的,以至于将某事物变成业务逻辑。
任何用户界面都依赖于模型对象的属性和操作。当然,我们可以引入一些中介层来屏蔽用户界面对我们模型的直接依赖,但这只是将依赖转移了;它并没有消除依赖,也没有解决哪个逻辑属于哪个层的确切问题。不清楚的是确定哪些逻辑必须由模型实现,哪些可以安全地实现在使用模型的用户界面(或中介层)代码中的标准。
我们经常谈论 业务逻辑
,所以你可能认为这是一种定义良好的概念,但正如维基百科 承认,
业务逻辑是一个非技术术语 ... 在任何编程语言规范或API中,在任何学术研究中,都不存在业务逻辑的定义 ... 应该注意的是,业务逻辑是一个定义不明确的术语,被不同群体的人以不同的方式使用。
尽管如此,维基百科继续为这个术语定义了以下 范围
业务逻辑
- 模型化现实生活中的业务对象(例如账户、贷款、行程和库存)
- 规定了业务对象之间如何相互交互
- 强制执行业务对象访问和更新的路径和方法
斯蒂芬的代码示例并没有定义业务对象,也没有定义业务对象之间的交互,而且在我看来,它似乎也没有强制执行业务对象访问和更新的路径和方法
。
所以,假设这个表达式在我的模板中没有出现在多个地方,我倾向于保留原始代码。在我看来,引入一个新方法(可能是一个新对象)来封装这个表达式的复杂性成本不值得付出这样的努力,除非有其他额外的具体好处。
另一方面,如果这个相同的表达式出现在多个地方,我几乎肯定会将其封装在一个模型对象的某个方法中
- 以满足DRY原则,
- 并允许我通过方法名称(甚至JavaDoc)来记录这个表达式的确切含义;这个表达式为什么如此/特殊/,以至于它反复出现。
那么,这让我成为JSP、PHP或RHTML中(短)脚本片段的使用者吗?不,我的反对理由不同。我认为令人反感的是,在同一个源文件中混合了高度不相似的语言和语言范式。我仍然是声明性用户界面定义的粉丝。