表示层与业务层分离

Posted

技术标签:

【中文标题】表示层与业务层分离【英文标题】:Separation of Presentation layer from Business layer 【发布时间】:2010-11-09 01:11:56 【问题描述】:

从我刚刚读到的一篇文章中,

UI Layer Abstraction

那么表示层和业务层之间的完全分离有什么挫折吗?

这个问题实际上来自于跟踪进程的进度(某些系列指令)并相应地更新进度条的问题。

现在唯一知道实际进度的是流程本身,也就是业务层。因此,如果两个层都非常独立,我怎样才能从业务层内到达进度条而不踩到表示层的域?或者至少将进度值返回给表示层?

【问题讨论】:

【参考方案1】:

恕我直言,关于分离层的对话框忽略了一个关键事实:虽然出于多种原因需要分离层,但这并不意味着它们不能做一些事情来使其他层的事情变得更容易。

我们有一个类似的要求 - 用于长期运行的业务流程的进度条。我们所做的是在业务层代码中定义进度事件。这些事件将在不同的时间被调用——例如完成百分比——并且“某人”订阅了它们。在我们的例子中,它是 UI 层!

所以这些层是分开的,但“业务”必须了解有人可能想观看它!

【讨论】:

是的,这就是我要做的。非常感谢,谢谢大家【参考方案2】:

依赖注入。

IOW 你的表示层实现了一些业务层回调接口(因此依赖关系是好的方向:ui->biz)并在运行时注册到业务组件。在这种情况下,业务组件将进度更新发送到其回调接口,而不关心“谁”在监听。

【讨论】:

【参考方案3】:

显然,业务层必须知道取得了哪些进展。然后它必须要么告诉表示层什么时候取得了进展,要么表示层必须询问业务层。随你喜欢。

关键是表示层不应该对已经取得的进展做出判断,业务层也不应该决定如何向用户展示信息。

问候

【讨论】:

感谢您以简单的方式表达! :-)【参考方案4】:

让表示层向业务层查询进度状态。

【讨论】:

【参考方案5】:

您也应该将“进度条”视为两个独立的逻辑部分。

用户看到的栏是 100% 呈现,因此所有使其增长的逻辑都应该包含在视图中。

您的业务层是否可以公开一个“ProgressUpdated”事件,该事件只是每 X% 触发一次。

视图将订阅所述事件,并在 UI 上有意义地显示。

【讨论】:

【参考方案6】:

“内”层能够调用“外”层中的代码,只要外层指定回调代码是什么。这可以通过对象、接口、委托或函数指针来表达,具体取决于语言。

void DoSomethingLengthy(string arg1, Action<double> progressCallback)

    // during the operation
    progressCallback(0.5); // halfway


DoSomethingLengthy("blah", progress => bar.Value = 100 * progress);

【讨论】:

【参考方案7】:

我发现的另一个是业务层的元数据 - 例如数据库中的字段长度和唯一性 - 是表示层需要了解的内容。

您可以从业务层导出它,也可以将其放在两者共享的公共模块中,但重要的是,您最终不会在业务层中复制与数据库字段长度和表示层中相同的信息作为输入约束。

【讨论】:

以上是关于表示层与业务层分离的主要内容,如果未能解决你的问题,请参考以下文章

外观模式

外观模式(Facade)C++实现

将服务层与验证层分离

实现服务层方法的指南

知识点总结

业务层与服务层的服务引用