代码之家  ›  专栏  ›  技术社区  ›  Scott McKenzie

我从未遇到过一个写得很好的业务层。有什么建议吗?

  •  13
  • Scott McKenzie  · 技术社区  · 17 年前

    我环顾四周,看到了一些用于定义规则、验证、业务对象(实体)等的代码片段,但我不得不承认,我从来没有看到过完整的、编写良好的业务层。

    我只知道我不喜欢什么,却不知道什么是伟大的。

    谁能指出一些好的OO业务层(或伟大的业务对象)或让我知道他们如何判断一个业务层以及什么使一个业务层伟大?

    谢谢

    9 回复  |  直到 13 年前
        1
  •  5
  •   Mark Cidade    15 年前

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

    正如一个好的数据库模式设计应该捕获业务语义并将自己与任何应用程序隔离一样,一个业务层应该做同样的事情,即使一个数据库模式和一个业务层描述了相同的实体和概念,这两者也应该在不同的上下文中可用——即使在总线上,数据库模式也不应该改变除非模式不反映当前业务,否则iness逻辑会更改。业务层应该与任何存储模式一起工作,前提是它是通过中间层进行抽象的。例如,ADO.NET实体框架允许您设计 概念的 映射到业务层并具有到存储架构的单独映射的架构,可以在不重新编译业务对象层或概念层的情况下更改该架构。

    如果业务方面的人员可以查看用业务层编写的代码,并大致了解正在发生的事情,那么这可能是对象设计正确的一个很好的指示——您已经成功地在问题域中传递了一个解决方案,而没有用解决方案域中的工件混淆它。

        2
  •  14
  •   Alex B    17 年前

    我从未遇到过一个写得很好的业务层。

    这里是 Alex Papadimoulis's take on this :

    […]如果您考虑一下,实际上是软件中的每一行代码 应用程序是业务逻辑:

    • 客户数据库表, 其客户编号(char-13) 批准日期(日期时间),以及 SalesrepName(varchar-35)列: 业务逻辑。如果它不是_t,它是_d 就在表032第01列中, 第02列和第03列。
    • 这个 扩展百分之十的子程序 首次客户折扣: 当然是商业逻辑。和 希望不是软编码。
    • 和 突出显示过期的代码 红色发票:该公司的业务 逻辑也是如此。Internet Explorer 当然不会找字符串 __unpaid_和__30+天_然后走,嘿, 背景990000,看起来不错!

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

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

        3
  •  6
  •   Edward Z. Yang    17 年前

    我想这是因为商业逻辑,作为一般规则,是武断和肮脏的。垃圾进,垃圾出。

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

        4
  •  3
  •   Kozyarchuk    17 年前

    马丁·福勒写了大量关于DSL的博客。我建议从那里开始。

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

        5
  •  3
  •   Travis Parks    13 年前

    我一直被困在岩石和坚硬的地方之间。理想情况下,您的业务逻辑根本不关心与数据库或UI相关的问题。

    钥匙导致问题 不过,我发现像主键和外键这样的东西会导致问题。甚至像实体框架这样的工具也不能完全消除这种蔓延。将作为Post数据传递的ID转换为它们各自的对象可能非常低效,只需将其传递给业务层,然后再传递给数据层,以便再次剥离。

    甚至NoSQL数据库也有问题。它们倾向于返回完整的对象模型,但它们通常返回的量比您需要的多,并且可能导致问题,因为您假设对象模型不会更改。在NoSQL数据库中仍然可以找到键。

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

    所以,我看到许多业务层类接受直接映射到数据库表(数据传输对象)的对象。我还看到许多业务层接受原始UI值(表示对象)。看到业务层调用数据库中间计算来检索所需的数据也是正常的。试图提前获取它可能效率很低(考虑语句如何和if会影响检索到的数据),而延迟加载的值会导致对数据库的大量神奇或意外调用。

    先写你的逻辑 最近,我一直在尝试先编写“核心”代码。这是执行实际业务逻辑的代码。我不知道你的情况,但很多时候当我浏览别人的代码时,我会问一个问题,“但是,它在哪里[商业规则]?”通常,业务逻辑中充满了对获取数据、转换数据以及其他我甚至看不到的问题(如草堆中的针)。所以,现在我首先实现了逻辑,当我弄清楚需要什么数据时,我把它作为一个参数添加或者添加到一个参数对象中。让其余的代码适应这个新接口通常属于某种类型的中介类。

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

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

    结论 我的结论是,真正没有完美的业务层。即使在同一个应用程序中,有时一种方法只工作90%。我们能做的最好的事情就是写一个最简单有效的东西。在很长一段时间内,我避免了DTO,并用对象包装了ADO.NET数据行,以便在底层数据表中立即记录更新。这是一个巨大的错误,因为我无法复制对象和约束,导致异常在奇怪的时候被抛出。我这样做只是为了避免显式地设置参数值。

        6
  •  2
  •   JasonS    17 年前

    学习和玩耍对我很有帮助 CSLA.Net (如果你是女士)。我从未实现过“纯”的CSLA应用程序,但使用了体系结构中提供的许多思想。

    你最好的选择是继续寻找那颗难以捉摸的魔法子弹,并运用最适合你正在解决的问题的想法。保持简单。

        7
  •  2
  •   Craig    17 年前

    我发现的一个问题是,即使您有一个设计良好的业务层,也很难阻止业务逻辑泄漏,开发工具往往会鼓励这样做。例如,一旦您向ASP.NET Web窗体添加了一个验证程序控件,您就让业务逻辑泄漏到视图中。验证应该在业务层中进行,并且只有它的结果显示在视图中。一旦您向数据库添加了约束,那么您的数据库中也就有了业务逻辑。DBA类型倾向于强烈反对最后一点。

        8
  •  0
  •   Community Mohan Dere    8 年前

    我也没有。我们没有在应用程序中创建业务层。相反,我们使用 MVC-ARS . 业务逻辑嵌入在(s)状态机和(a)操作中。

        9
  •  -1
  •   Draemon    17 年前

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