我正在与一位同事“讨论”在新应用程序中实现数据层的最佳方法。

一种观点是数据层应该了解业务对象(我们自己的代表实体的类),并且能够在本机使用该对象。

相反的观点是数据层应该与对象无关,并且纯粹处理简单的数据类型(字符串、布尔值、日期等)

我可以看到这两种方法可能都是有效的,但我自己的观点是我更喜欢前者。这样,如果数据存储介质发生变化,业务层就不必(必然)进行更改以适应新的数据层。因此,从 SQL 数据存储更改为序列化 xml 文件系统存储将是一件微不足道的事情。

我同事的观点是,数据层不必了解对象定义,只要数据适当传递就足够了。

现在,我知道这是有可能引发宗教战争的问题之一,但我希望社区能够就如何处理此类问题提供任何反馈。

TIA

有帮助吗?

解决方案

这实际上取决于你对世界的看法——我曾经属于不成双成对的阵营。DAL 的作用只是向 BAL 提供数据——故事结束了。

随着 Linq to SQL 和 Entity Framework 等新兴技术变得越来越流行,DAL 和 BAL 之间的界限已经变得有点模糊。特别是在 L2S 中,您的 DAL 与业务对象紧密耦合,因为对象模型与数据库字段具有 1-1 映射。

就像软件开发中的任何事情一样,没有正确或错误的答案。您需要了解您的需求和未来的需求,并从那里开始工作。我不会再在达哈尔拉力赛上使用法拉利,就像我在赛道日使用路虎揽胜一样。

其他提示

你可以两者兼得。让数据层不知道您的业务对象,并使其能够处理多种类型的数据源。如果您提供用于与数据交互的公共接口(或抽象类),则可以为每种类型的数据源拥有不同的实现。工厂模式在这里很适合。

我有一本很棒的书,涵盖了这个主题,是 数据访问模式, ,作者:克利夫顿·诺克。关于如何将业务层与持久层解耦,它提供了许多很好的解释和好主意。你真的应该尝试一下。这是我最喜欢的书之一。

杰弗里·巴勒莫(Jeffrey Palermo)就此写了一篇很好的文章。他称之为 洋葱架构.

我发现一个方便的技巧是让我的数据层“与集合无关”。也就是说,每当我想从数据层返回对象列表时,我都会让调用者传入该列表。所以代替这个:

public IList<Foo> GetFoosById(int id) { ... }

我这样做:

public void GetFoosById(IList<Foo> foos, int id) { ... }

如果我需要的话,这可以让我传入一个普通的旧列表,或者如果我计划从 UI 绑定到它,则可以传入 IList<T> 的更智能的实现(如 ObservableCollection<T>)。这项技术还允许我从方法中返回一些内容,例如 ValidationResult,其中包含错误消息(如果发生错误)。

这仍然意味着我的数据层知道我的对象定义,但它给了我额外的灵活性。

查看 Linq to SQL,如果我现在要创建一个新应用程序,我会考虑依赖完全基于 Linq 的数据层。

除此之外,我认为尽可能地分离数据和逻辑是一种很好的做法,但这并不总是可行的。逻辑和数据访问之间的纯粹分离使得连接和优化变得困难,而这正是 Linq 如此强大的原因。

在我们使用 NHibernate 的应用程序中,答案变成“介于两者之间”,因为 XML 映射定义(它们指定哪个表属于哪个对象以及哪些列属于哪个字段等)显然位于业务对象层中。

它们被传递给通用数据会话管理器,该管理器不知道任何业务对象;唯一的要求是传递给它进行 CRUD 的业务对象必须有一个映射文件。

旧帖子,但搜索我遇到的类似信息 这很好地解释了这一点。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top