n 层架构 - BLL、DAL 和接口。啥是最佳实践?
Posted
技术标签:
【中文标题】n 层架构 - BLL、DAL 和接口。啥是最佳实践?【英文标题】:n-layered architecture - BLL, DAL and interfaces. What is best practice?n 层架构 - BLL、DAL 和接口。什么是最佳实践? 【发布时间】:2011-03-08 12:05:45 【问题描述】:我有一个关于 n 层架构的问题。在问这个问题之前我想了很久,因为这里已经有很多类似的问题了......但是,在看了一天半之后,我仍然不确定。各种看似相似的术语和不同的方法让我感到困惑。
如果我在不同的类库中有一个 BLL 和一个 DAL,那么在 BLL 和 DAL 之间进行通信的一种方法是使用一个接口,有点像在另一个单独的 DLL 中定义的 DTO,它同时被 BLL 和 DAL 引用. BLL 中的域模型实体将实现此接口,DAL 中的任何 ORM 生成的对象也将实现此接口。为了保存我的业务实体,我可以将它们传递给 DAL,DAL 会很好地接受它们,因为它们实现了共享接口。我还可以将对象传递回实现此接口的 BLL。这似乎是合理的,因为 BLL 和 DAL 只需要了解基本接口,而不是彼此的具体实现。
我的问题是在另一端创建对象的最佳方法是什么?例如,如果我在 BLL 中有一个实现 IPerson 的 Person 对象,以及一个 PersonDataObject 或 DLL 中也实现 IPerson 的任何东西,我将 Person 传递给 DAL 中的一个方法,该方法采用 IPerson 的参数,然后在 DAL 中我d 必须重建 PersonDataObject 才能持久化。这甚至是最好的方法吗?
抱歉,我可能没有很好地解释这一点,因为我很困惑。非常感谢虚拟答案的最佳实践。
【问题讨论】:
【参考方案1】:Google 用于域驱动设计和存储库模式。听起来您的架构正朝着这个方向前进,并且根据场景需要,我会在更复杂的代码上使用这种方法。
【讨论】:
【参考方案2】:一般来说,BLL 中的对象会消耗接口——而不是实现它们:
例如,如果我有一个 Person 对象 在实现 IPerson 的 BLL 中, 和 PersonDataObject 或任何东西 也实现 IPerson 的 DLL
以“人”为例:考虑与一个人相关的不同数据操作(获取单个人的所有数据、多个人的浅层数据集合、CRUD 操作、搜索等)- 然后沿着逻辑分组设计接口(参见Interface Segeragtion Principle)。
接口可能从以 BL 为中心的角度或基于“服务”的角度表示操作。
无论如何,回答你的具体问题......
我在一个通用程序集中定义了我的等效 DTO,并且在一个单独的程序集中定义了数据接口 - 所以我有 4 个程序集:BL、数据访问接口定义、接口实现和通用;所有程序集都引用公共程序集。
我在 C#.Net 中工作,我将 DTO 定义为结构(但您可以使用类);并且这些属性的所有属性都是只读的 - 您在构造函数中将数据输入它们 - 这样 DTO 就实际上是“愚蠢”的信息信封。
【讨论】:
还有一点我忘了包括:让 BL 调用负责实例化具体实现的“工厂”方法;我倾向于在配置中将这些定义为易于更改。【参考方案3】:虽然遵循 n 层架构,但在 BL 和 DAL 之间共享数据对象是很常见的。有时,同样的数据对象也可以在 UI 层中使用。
通常我有一个数据模型(或数据对象或域模型,无论你如何命名)程序集,它包含所有模型对象作为接口。以您的人员为例,我将在模型装配中创建一个 IPeople 接口。 DAL 将 IPeople 的一个实例返回给 BL。 BL 将使用此实例,如果需要,在应用业务逻辑后将其传递给 UI 层。
【讨论】:
以上是关于n 层架构 - BLL、DAL 和接口。啥是最佳实践?的主要内容,如果未能解决你的问题,请参考以下文章
在ASP.NET中,三层架构,Web ,BLL,DAL,Models这四个的引用关系是?
业务层 (BLL) 数据访问层 (DAL) 和 UI 之间的通用结构?
除了实例化 DAL 的 BLL 之外,还有啥选项允许在 n 层解决方案中进行单元测试,而不会将 DAL 暴露给 UI 或将 BLL 暴露给 DAL?