【问题标题】:Architectural question for tier .Net Development.Net 开发层的架构问题
【发布时间】:2010-10-21 11:50:34
【问题描述】:

大家好,我对分层开发过程还很陌生。我目前正在开发一个应用程序,我有一些关于当今技术的最佳实践/架构问题的基本问题。我将使用 WCF 作为服务层。请注意,我正在尝试尽可能多地解耦。我不希望上层的任何事情都必须了解下层的任何事情,这是我不喜欢 LINQ TO SQL 或实体框架的原因之一。

1) 在层之间传递数据的最佳方式是什么?我知道数据集或数据表都很容易,但我认为在层之间传递这种臃肿的数据结构并不是最好的解决方案。如果数据表/数据集很大,调试也会更加困难。一组 POCO 对象可能是最好的解决方案还是有更好的方法?

2) 下一个问题有点棘手。许多应用程序会有一堆不同的数据视图。您可能有多个报告、各种数据网格,可能还有一个或两个图表。您如何为此设计数据层?您是否只是为每个表设计一个“获取”类型的函数,然后尝试将它们组合成有用的视图,例如您的业务层中的网格或报告,或者您是否为业务层中需要的每个视图提供了一个专门的函数。

说实话,我不喜欢这两种解决方案。如果您决定每个视图的专用逻辑,那么您需要为每个视图创建一个 POCO 对象(假设您将返回一个 POCO 对象数组)。如果您稍后决定需要向其中一个视图添加更多列,那么您将破坏现有代码(因为您更改了 POCO 上的界面)。如果您决定返回每个表的视图并尝试将其组合到业务层中,那可能会变得非常混乱。 TSQL 有连接是有原因的:)。此外,您可能会返回比您需要的更多的数据,具体取决于您的设计,这将是低效的。

我还有一些问题,但我会留到以后。我不希望这篇文章变得太大:)

笼子

【问题讨论】:

    标签: .net architecture n-tier-architecture


    【解决方案1】:

    好问题。重要的东西,这个。通常,处理分层解决方案的最佳方法之一是查看接口。接口是提供“阻塞点”的一种方式,它可以用于多种有用的目的。

    在分层解决方案中,接口用于强制执行层的行为;通过定义您期望的一组行为,您可以有效地解耦层的实现。也就是说,只要我的层正确实现了接口,实现是我根本不需要关心的。

    我提出这个(并且它是相关的)是因为在定义接口时,您还需要定义在层之间传递的数据。因此,在定义层之间需要发生的事情时,您最终会定义要传递的数据;同时,定义了一组严格的传递数据。

    这里关于隔离的一个相关点是,不应该在层之间传递有关层实现的信息。也就是说,通过定义您的接口并严格执行,您应该能够使该层的实现可以从头开始重新实现,只知道接口,并且可以毫无问题地替换其他实现。

    知道这一点会使事情变得简单;使用普通旧对象通常会使您的界面保持干净和正确;它可以防止您的数据结构变得臃肿。它还有助于防止在另一层中使用有关某一层实施的一些信息的诱惑。

    当然,要正确地做到这一点,从长远来看要解决的问题是有用的;用户想要执行的操作集是什么?这些操作通常将自己解析为“动词”,这些“动词”很好地映射到定义业务对象将实现的合同的接口定义。您的业​​务对象将对其进行操作的数据集将定义您需要在数据库上拥有的一组视图。这样,您就可以干净利落地保持分离。

    【讨论】:

    • 感谢您的回复。是的,由于 WCF,我肯定会使用接口。一般来说,我总是使用接口。我几乎从不直接针对我创建的对象进行编程。接口总是要走的路。您认为您应该采取按需要查看的方法还是按表查看。您还必须考虑必须将这些 POCO 发回以进行插入/更新,因此您可能总是至少需要为每个表提供一个 poco。
    • 根据需要查看。绝对地。无论如何,视图都包含(或应该)从多个表中获取的数据。我强烈不同意将对象绑定到表定义的想法。这样想;我不需要知道超市带的所有蔬菜来做饭;我只需要知道我正在看的食谱的成分。无论如何,我从哪里得到这些成分是无关紧要的! :-) 这有意义吗?
    【解决方案2】:

    这些都是非常好的问题。有很多可能的答案和很多可能的架构。我建议您阅读有关该主题的入门读物。 Patterns & Practices has a very good one。它是免费的、全面的,并深入讨论您提出的问题。没有一个架构指南是完美的,但作为一个起点,我认为学习基础知识不会出错。

    【讨论】:

    • 感谢 JP,我会查看模式和实践指南,看看它们是否对我有帮助
    【解决方案3】:

    我认为您不希望数据层了解有关业务或 UI 层的任何信息的想法有点遗漏。在 ORM 工具(例如 LINQ to SQL)中,实体的属性由数据决定。真的没有理由不这样做。拥有强类型实体与在数据层拥有业务/UI 逻辑不同,通常是一件好事;如何到达那里取决于您。

    我始终提倡使用强类型组件来传递数据,而不是像 DataSet/Table/Row/View/etc 这样的通用存储库。

    也许您可以详细说明是什么让您远离了这种方法?

    【讨论】:

    • 这样想……如果你这样设计你的系统,那么你将不得不在你的业务层和客户端层中引用你的数据层。这是一个好的设计吗?如果您因为向数据库添加了列而破坏了数据层上的接口怎么办。您刚刚破坏了每个客户端,并且更改必须部署到 N 个客户端,除非您不返回匿名类型。此外,您不能跨层 (WCF) 传递数据上下文对象。
    • 但是提到的是UPPER不知道LOWER,而不是LOWER不知道UPPER,这就是你在这里描述的。确切地说,您在这里指的是什么“层”?这些只是解决方案中的不同项目吗?同一台机器上的不同进程?完全不同的机器?
    • 而且,顺便说一句,您不能在其创建范围之外返回匿名类型(换句话说,您不能在外部返回匿名类型(作为“对象”除外)一个函数。
    猜你喜欢
    • 2021-07-23
    • 2013-09-27
    • 2012-02-27
    • 2012-03-12
    • 2011-04-03
    • 2022-01-14
    • 2011-04-13
    相关资源
    最近更新 更多