如何在保持效率的同时将用户界面与业务逻辑分开?


19

假设我想显示一个表示组合框上10个不同对象的表单。例如,我希望用户从10个不同的包含番茄的汉堡包中选择一个。

因为我想分离UI和逻辑,所以我必须通过表单来表示汉堡包的字符串,以便在组合框中显示它们。否则,UI必须深入到对象字段。然后,用户将从组合框中选择一个汉堡包,并将其提交回控制器。现在,控制器将不得不根据表单使用的字符串表示形式(也许是ID?)再次查找所述汉堡包。

这不是效率低下吗?您已经有了想要从中选择一个的对象。如果您将整个对象提交给表单,然后返回一个特定的对象,则以后不必重新引用它,因为表单已经返回了对该对象的引用。

而且,如果我错了,而您实际上应该将整个对象发送到表单,那么如何将UI与逻辑隔离?


用哪种方式效率低下?在所有情况下,您都必须向用户显示字符串表示形式,并将其答案映射到原始对象。
西蒙·贝尔格

问题是,为了使用所述对象,我必须在用户选择它之后再次获取它。
Uri

Answers:


34

首先,您提供的示例并非效率低下。它只是效率低下;它的效率低于可感知的水平。但是,无论如何,让我们继续这个问题。

以我的理解,当我们谈到UI和逻辑分离时,是指避免紧密耦合

紧密耦合是指UI知道(并调用)逻辑并且逻辑知道(并调用)UI的情况。为了避免紧密耦合,不必完全取消耦合。(这就是通过将它们之间的接口降级为最小公分母的字符串接口来达到的目的。)所有需要做的就是采用松耦合

松散耦合意味着A知道B,但B不知道A。换句话说,所涉及的两方扮演着不同的客户端服务器角色,其中客户端知道服务器,但是服务器不知道客户端。

就UI和逻辑而言,我认为最好的安排方式是将逻辑视为服务器,将UI视为客户端。因此,UI是为逻辑构建的,具有逻辑知识,并可以调用逻辑,而逻辑对UI则一无所知,只需响应其收到的请求即可。(这些请求恰好来自UI,但是逻辑并不知道。)

用更实际的术语来说,在逻辑的源代码文件中应该找不到任何引用UI文件的include / import / using语句,而UI的源代码文件将充满了include / import / using引用逻辑文件的语句。

因此,回到您的情况来看,填充组合框的UI代码了解汉堡包类这一事实绝对没有错。如果汉堡班对组合框一无所知,那将会是一个问题。

顺便说一句,这种设计允许您从该系统中获得另一件事:应该可以向逻辑中插入任意数量的不同UI,并且整个事情仍然可以进行。


5

您应该将模型,视图和控制器的每个部分分开,但是没有理由不能(例如)在控制器和视图之间传递模型对象。

因此,在您的情况下,Hamburger对象将是模型的一部分。然后,您可以使用Controller获取所需的Hamburgers 列表,并将这些对象传递给View(组合框)以显示。当您的用户选择了哪个汉堡包后,您可以将该Hamburger对象再次传递回Controller进行处理。

关键是,您仍然可以与汉堡包的实际显示分开对“ fetch Hamburgers”逻辑和“ process Hamburger”逻辑进行单元测试。


我明白。但是,如果我修改了Hamburguer类,是否也不必修改处理Hamburguer对象的表单代码?UI-Logic分离在哪里?
Uri

2
汉堡包是模型的一部分。修改模型时,最终将修改视图和控制器。该模型是UI和逻辑之间的分离。触摸它的成本较高,因此在设计时应格外小心。
西蒙·贝格
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.