17

我对感知到的“最佳实践”感兴趣,这里有一点现实。

在 Web 应用程序中,您是允许您的 Web 层直接访问 DAL,还是应该先通过 BLL?

我说的是没有真正涉及“业务逻辑”的场景——例如一个简单的查询:“获取所有姓氏为 'Atwood' 的客户”。有任何逻辑的场景绝对会通过 BLL,所以我们称之为moo

虽然您可以将此方法封装在 BLL 对象中,但如果签名通常与 DLL 对象的签名完全相同,并且代码可能像将查询委托给 DLL 的单行代码一样简单,这似乎有点毫无意义.

如果你选择前者——使用 BLL 对象——你怎么称呼这些对象?(假设他们只是在 DLL 中提供一个查询层)。帮手?查询提供者?

请思想。

问候

马蒂

4

7 回答 7

37

我不同意这里的大多数帖子。

我在 Web 层中调用我的数据层。如果 WEB/UI 层之间没有任何内容,那么创建一个“以防万一”层是没有意义的。是预优化。这是一种浪费。我不记得业务层“拯救了我”的时间。它所做的只是创造了更多的工作、重复和更高的维护。我花了数年时间订阅业务层 --> 数据层在层之间传递实体。我总是觉得通过什么都不做的方法创建传递是肮脏的。

在被Eric Evans介绍给领域驱动设计之后,我做了有意义的事情。如果 UI 和数据层之间没有任何内容,那么我在 UI 中调用数据层。

为了允许将来进行更改,我将所有数据层类包装在接口中。在 UI 中,我引用接口并使用依赖注入来管理实现。做出这些改变之后,就像呼吸到了一股新鲜空气。如果我需要在数据层和 UI 之间注入一些东西,我会创建一个服务。

我做的另一件事是减少项目的数量。在我有一个数据层、业务逻辑、业务实体和某种类型的 UI 项目的项目之前——真是太痛苦了。

我有两个项目:核心项目(实体、业务逻辑和数据层)和 UI 项目(Web、Web 服务等...)

有关更多信息,我建议查看这些人:

于 2009-04-28T09:16:30.377 回答
4

在我看来,您应该始终在 Web 层和 DAL(数据访问层)之间使用 BLL(业务逻辑层)。

我很欣赏对于一些更“简单”的查询,BLL 将密切模仿 DAL(例如获取所有国家/地区,获取所有产品类型等),但老实说,即使在您的示例中:

(获取所有姓氏为“Atwood”的客户)

这里表达了“业务逻辑” - 如果没有别的,希望按姓氏过滤数据记录!

通过从项目一开始就实施 BLL,在需要时插入验证或附加“逻辑”变得非常容易(如果您的项目是商业应用程序,那么几乎肯定会最终出现这种需求,如果它不是'在项目开始时不在那里)。添加其他逻辑,例如:

获取所有今年花费超过 10000 美元的客户

或者

不允许姓“阿特伍德”的顾客购买超过 1000 美元的商品

当涉及到真正的 BLL 时,它变得非常容易,而不是试图将这个逻辑推入 Web 层。

请记住,对于上述类型的查询,我们几乎可以肯定地谈论多个实体和数据库表,它们必须通过特定定义的关系连接在一起才能实现此功能。试图通过直接操作 DAL 来实现这一点变得很麻烦,因为您将处理多个实体和类。此处的 BLL 将大大简化您的 Web 层代码,因为 BLL 将把这些实体关系封装在一个大大简化的接口后面。

当需要更改用户界面时,这种“关注点分离”变得越来越重要。

现在至少有两个不同的场合,我曾在具有网站用户界面的商业 Web 应用程序上工作,并且最终被要求(由于客户寻求在其软件产品中进行更大程度的集成而产生的业务需求)生成Web 服务界面提供与网站完全相同的功能。

如果我在我的 Web 层中嵌入了任何业务逻辑,我将不得不在实现我的 Web 服务时复制并重新编写该逻辑。事实上,我确保所有业务逻辑都封装在 BLL 类中,这意味着我只需要设计一系列 Web 服务接口方法调用,并将它们插入到 BLL 类上的方法调用中(我实际上使用了外观设计模式用于简化 Web 服务 API)。

总之,我想不出任何理由不在的 DAL 和我的 Web 层之间包含 BLL 层。

最简单的情况是,当 BLL 密切“模仿” DAL 时,是的,确实存在代码和功能的重复,但是,虽然需要更多的输入,但这也使得它相对容易实现。

当涉及更多时(例如从一开始就存在重要的业务逻辑时),关注点分离有助于减少重复(DRY原则),同时显着简化未来和持续的维护。

当然,这假设您正在“手动”完成所有这些工作。如果您愿意,您可以通过使用有很多ORM来显着简化 DAL/BLL/UI 层!(即LINQ-to-SQL/EntitiesSubSonicNHibernate等)

于 2009-04-28T08:40:22.023 回答
2

您需要区分 BLL 对象(这些到底是什么?域对象吗?)和服务。您的域对象应该与您的数据访问层无关。就 Web 层而言,它可以像对待IRepository它可以自由使用的任何其他服务一样对待您的存储库(想想)。

所以底线是:是的,Web 层可以直接使用 DAL,前提是它被属性封装并表示为标准的服务层服务。

于 2009-04-28T07:40:31.107 回答
1

即使在 BLL 中的一行对 DLL 进行类似调用时,它也允许您在该层中添加业务逻辑,而无需影响任何其他层。现在可能看起来不太可能,但是在您之后必须支持该应用程序的人会感谢您在发生更改时使用这样的模式。

至于命名,我有我的核心对象,比如 NameChange,然后我将有一个 BLL 对象,它是一个接受名称更改对象的人,然后我将有一个称为 Person 的 DAL/Entity 对象。业务人员对象位于 BLL 命名空间中,而 DAL/实体人员对象位于 DB 命名空间中(如果我最初构建它,我会选择 DAL)。

于 2009-04-28T07:39:19.847 回答
1

我们将此层称为控制器类 [层],它封装了来自 Web 层的 DAL。控制器层可能有也可能没有任何业务逻辑,它确实有助于将 DAL 与表示层分离并保持它们独立 [在某种程度上]。

于 2009-04-28T07:45:38.957 回答
0

我们倾向于使用外观模式进行访问,尽管我们使用它的项目规模很大,但我认为在较小的项目中它可能会被证明是矫枉过正。

本质上:

UI -> BusFacade -> BusinessLogic -> DalFacade -> DataAccessLayer

外观为 UI 提供了一种漂亮/干净的方法,并迫使您标准化命名约定,因为单个入口点有许多方法。

BusFacade.GetCmsSiteMap()
BusFacade.GetProductGroup()

等等等等

于 2009-04-28T07:55:21.417 回答
0

虽然可以直接从表示层转到 DAL,但您正在跳过通常需要身份验证的 BLL...

于 2009-04-28T15:20:53.967 回答