【问题标题】:I've never encountered a well written business layer. Any advice?我从未遇到过编写良好的业务层。有什么建议吗?
【发布时间】:2010-09-17 00:37:27
【问题描述】:

我环顾四周,看到了一些用于定义规则、验证、业务对象(实体)等的很棒的 sn-ps 代码,但我不得不承认,我从未见过一个完整的出色且编写良好的业务层.

我只知道自己不喜欢什么,但不知道什么是伟大的。

谁能指出一些好的 OO 业务层(或出色的业务对象),或者让我知道他们如何判断一个业务层以及是什么让一个业务层变得出色?

谢谢

【问题讨论】:

    标签: oop n-tier-architecture business-logic-layer


    【解决方案1】:

    Martin Fowler 发表了大量有关 DSL 的博客。我建议从那里开始。

    http://martinfowler.com/bliki/dsl.html

    【讨论】:

    • 很抱歉,福勒的建议很蹩脚……太理论化和深奥以至于失去了适用性。
    • 我必须同意这里的 dacracot。福勒被高估了。
    • Fowler 的 DSL 书很不错。它对构建业务层的适用性是有限的。它更倾向于制作用于定制业务分析师可以编写的业务逻辑的语言。DDD 书更适用于这个问题。甚至福勒的分析模式或 POEAA 也更适用。
    【解决方案2】:

    我想这是因为业务逻辑,作为一般规则,是任意的和令人讨厌的。垃圾进,垃圾出。

    此外,大多数真正优秀的业务层很可能是专有的。 ;-)

    【讨论】:

    • 我必须同意。有谁知道任何好的、非专有的例子?
    • +1。我知道至少有两个很好的例子,但由于我处于 NDA 之下,所以无法提供来源。
    【解决方案3】:

    我也没有。我们不会在应用程序中创建业务层。相反,我们使用MVC-ARS。业务逻辑嵌入在 (S) 状态机和 (A) 动作中。

    【讨论】:

    • 你能再描述一下吗?
    • 我们实现了2层,一层是Web服务器,二是数据库服务器。每个都遵循 MVC 模式。然而,在数据库中,该模式称为 ARS 以保持词汇表的正确性。 Representation 非常像 View,StateMachine 非常像 Contoller,但是......
    • ...它们在模型和动作方面存在分歧。模型等于服务器之间的表示。 Action 更容易理解为处理数据的 SQL。 Web 服务器中的控制器更像是一个路由器,将操作推送到其他组件。清如泥?
    【解决方案4】:

    我从来没有遇到过写得很好的业务层。

    这里是Alex Papadimoulis's take on this

    [...] 如果你仔细想想,软件中的几乎每一行代码 应用是业务逻辑:

    • Customers 数据库表,其中包含 其客户编号 (CHAR-13), 批准日期(日期时间),和 SalesRepName (VARCHAR-35) 列: 商业逻辑。如果不是,那就是 只是 Table032 和 Column01, Column02 和 Column03。
    • 扩展百分之十的子程序 首次客户折扣: 绝对是业务逻辑。和 希望不是软编码。
    • 和 突出显示逾期的代码 红色发票:这是生意 逻辑也是。 IE浏览器 当然不会寻找字符串 “未付”和“30 多天”然后去,嘿, 用#990000 背景肯定会很好看!

    那么如何封装所有这些业务逻辑 在单层代码中?和 糟糕的架构和糟糕的代码 当然!

    [...] 通过暗示系统架构应该包括一个专门用于业务逻辑的层,许多开发人员采用了各种非常聪明的技术来实现这一目标。它总是以灾难告终。

    【讨论】:

    • 老实说,如果需要多个业务层来实现某件事,我认为这仍然是一种优雅的方法。这些层之间可能并且理想情况下会保持一致性,这将使其被视为一个好的层。
    • 哇,我不敢相信这个完全不正确的报价获得了多少票。这些天来,如果您没有在数据层中使用 ORM 框架,那么您可能做错了——对于所有数据层关心的问题,它实际上可能是 Table032、Column01、Column02——它不是业务逻辑。第二点是业务逻辑,不错。第三点是100%表示层,不是业务逻辑。您的过期发票应该有某种状态标志或 IsPastDue 属性,表示层正确地呈现为红色或其他。同样,演示文稿不是业务逻辑。
    【解决方案5】:

    可能是因为在现实中我们永远无法将业务逻辑与“流程”、输入、输出、接口完全解耦,最终人们发现很难处理抽象,更不用说将其与现实联系起来了。

    【讨论】:

      【解决方案6】:

      CSLA.Net 一起学习和玩耍对我很有帮助(如果您是 MS 专家)。我从未实现过“纯”CSLA 应用程序,但使用了架构中提出的许多想法。

      您最好的选择是继续寻找难以捉摸的灵丹妙药,并使用最适合您正在解决的问题的想法。保持简单。

      【讨论】:

        【解决方案7】:

        经过彻底的领域分析,设计出良好的业务层。如果您可以捕获业务的语义并将其与任何类型的实现隔离开来,无论是在数据存储中还是在任何特定应用程序(包括表示)中,那么逻辑应该是精心设计的并且可以在不同的上下文中重用。

        就像一个好的数据库架构设计应该捕获业务语义并将自己与任何应用程序隔离一样,业务层也应该这样做,即使数据库架构和业务层描述相同的实体和概念,两者也应该是可用的在不同的上下文中——即使业务逻辑发生变化,数据库架构也不必更改,除非架构不反映当前业务。业务层应该与任何存储模式一起工作,只要它是通过中间层抽象出来的。例如,ADO.NET Entity 框架允许您设计一个 conceptual 架构,该架构映射到业务层并具有到存储架构的单独映射,无需重新编译业务对象层或概念层即可更改该映射.

        如果业务方面的人可以查看使用业务层编写的代码并大致了解正在发生的事情,那么这可能很好地表明对象设计正确 - 您已经成功传达问题域中的解决方案,而不用解决方案域中的工件混淆它。

        【讨论】:

        • 我已经开始阅读领域驱动设计和创建实体的方法,这意味着某些东西似乎很关键;我认为它被称为“无处不在的流畅性”。这个想法似乎很合理,但我不确定实施。很好的回应,谢谢。
        【解决方案8】:

        我发现一个问题是,即使您有一个设计精美的业务层,也很难阻止业务逻辑泄漏,而开发工具往往会鼓励这种情况。例如,一旦您将验证器控件添加到 ASP.NET WebForm,您就会让业务逻辑泄漏到视图中。验证应该发生在业务层中,并且只有它的结果显示在视图中。一旦您向数据库添加约束,您的数据库中也会有业务逻辑。不过,DBA 类型往往强烈反对最后一点。

        【讨论】:

          【解决方案9】:

          我总是被困在一块石头和一个坚硬的地方之间。理想情况下,您的业务逻辑完全不关心数据库或 UI 相关问题。

          按键导致问题 尽管如此,我还是发现诸如主键和外键之类的东西会导致问题。即使是像 Entity Framework 这样的工具也不能完全消除这种蠕变。将作为 POST 数据传递的 ID 转换为它们各自的对象,仅将其传递给业务层,然后再将它们传递给数据层以再次被剥离,这是非常低效的。

          即使是 NoSQL 数据库也存在问题。它们倾向于返回完整的对象模型,但它们返回的通常比您需要的多,并且可能导致问题,因为您假设对象模型不会改变。并且在 NoSQL 数据库中仍然可以找到密钥。

          重用与开销 还有代码重用的问题。数据层返回完全填充的对象是很常见的,包括该特定表中的每一列。但是,业务逻辑通常只关心此信息的有限子集。它适用于仅携带相关数据的专用数据传输对象。当然,您需要在表示之间进行转换,因此您创建了一个映射器类。然后,当您保存时,您需要以某种方式将这些较小的对象转换回完整的数据库表示或执行部分更新(意味着另一个 SQL 命令)。

          所以,我看到很多业务层类接受直接映射到数据库表(数据传输对象)的对象。我还看到很多业务层也接受原始 UI 值(表示对象)。业务层在计算过程中调用数据库以检索所需数据的情况也很常见。尝试预先获取它可能效率低下(想想 if 语句如何影响检索到的数据),并且延迟加载的值会导致大量魔术或意外调用数据库。

          先写出你的逻辑 最近,我一直在尝试先编写“核心”代码。这是执行实际业务逻辑的代码。我不了解你,但很多时候在查看别人的代码时,我会问这样一个问题:“但是,它在哪里做 [业务规则]?”通常,业务逻辑充满了对抓取数据、转换数据等问题的关注,以至于我什至看不到它(大海捞针)。所以,现在我首先实现逻辑,当我弄清楚我需要什么数据时,我将其添加为参数或将其添加到参数对象。让其余代码适应这个新接口通常需要某种中介类。

          不过,正如我所说,在编写业务层时,您必须牢记很多事情,包括性能。上面的方法最近很有用,因为我还没有版本控制或数据库模式的权限。我在一个黑暗的房间里工作,到目前为止我只了解需求。

          在写作时考虑到测试 利用依赖注入对于预先设计好的架构很有用。尝试考虑如何在不访问数据库或其他服务的情况下测试代码。这也适用于可以在多个上下文中运行的小型、可重用类。

          结论 我的结论是,确实不存在完美的业务层。即使在同一个应用程序中,有时一种方法也只能在 90% 的时间内起作用。我们能做的最好的事情就是尝试编写最简单的东西。在最长的时间里,我避免使用 DTO 并使用对象包装 ADO.NET DataRows,因此更新会立即记录在底层 DataTable 中。这是一个巨大的错误,因为我无法复制对象,并且约束导致在奇怪的时间抛出异常。我这样做只是为了避免显式设置参数值。

          【讨论】:

            猜你喜欢
            • 2010-12-24
            • 2011-01-18
            • 1970-01-01
            • 1970-01-01
            • 2011-01-24
            • 2010-12-23
            • 1970-01-01
            • 2020-08-22
            • 1970-01-01
            相关资源
            最近更新 更多