【问题标题】:Business logic in Entity Framework POCOs using partial classes?使用部分类的实体框架 POCO 中的业务逻辑?
【发布时间】:2011-04-20 10:42:54
【问题描述】:

我的业务逻辑可以位于业务逻辑/服务层中,也可以添加到利用部分类功能的扩展域类(EF T4 生成的 POCO)的新成员中。

所以我可以:

a) bool OrderBusiness.OrderCanBeCancelledOnline(Order order) .. 或(订单订单)

b) bool order.CanBeCancelledOnline() .. 即能不能取消是订单自己知道的。

对我来说,选项 b) 更面向对象。然而,选项 a) 允许应用更复杂的逻辑,例如使用其他域对象或服务。

目前我两者兼而有之,这似乎并不优雅。

任何关于这方面的指导将不胜感激!

【问题讨论】:

    标签: frameworks entity-framework-4 entity poco partial-classes


    【解决方案1】:

    一个常见的问题,并且是部分主观的。

    IMO,您应该选择选项 A。

    POCO 应该就是“plain-old-CLR”对象。如果您开始对它们应用业务逻辑,它们就不再是 POCO 的了。 :)

    您当然可以将您的业务逻辑与您的 POCO 放在同一个程序集中,只是不要直接向它们添加方法,创建辅助类以促进业务规则。您的 POCO 唯一应该拥有的就是映射到您的域模型的属性。

    实际上取决于您的业务规则有多复杂。在我们的应用程序中,业务规则非常简单,因此我们使用选项 A。

    但如果您的业务规则开始变得混乱,请考虑使用规范模式。

    【讨论】:

    • 谢谢。我已经阅读了您所提议的“贫血域模型”。我不得不说这似乎与我的 OO 背景背道而驰,但我可以理解您为什么希望以这种方式保持 POCO 的清洁。
    • 对不起,POCOs 不应该包含业务逻辑的说法是完全错误的。它们可以并且通常确实包含行为和逻辑,它们不应该包含特定于框架的元素,例如特定于 ORM 的基类。您所描述的内容几乎看起来像是 DTO:DTO vs POCO
    • @Steve - 你是 100% 正确的。回到我很久以前给出的答案很有趣。 :)
    【解决方案2】:

    对我来说,OO 的关键在于你告诉对象为你做事。您不会提取属性并自己做出决定(在帮助类或其他类中)。

    所以我同意你关于选项 b) 的说法。由于您需要额外的逻辑,因此在对对象执行操作的同时将引用传递给其他辅助对象以使它们协作是没有害处的。无论您是在操作本身时执行此操作,还是使用这些协作实体预先填充您的订单对象,很大程度上取决于您当前的情况。

    【讨论】:

    • 谢谢布赖恩。只是为了澄清我给出的“CanBeCancelledOnline”示例可能是启用/禁用表单上的“取消订单”按钮的要求 - 所以在这种情况下,我确实需要“拉出属性并自己做出决定”(我会在许多情况下,争论并不违背 OO 范式)。
    • ... 让我们说(仅作为示例),为了确定订单是否可以取消,它需要了解有关客户合同的一些信息。又是两种选择。 a) OrderBusiness 类使用来自 Order 和 Contract 的信息(或逻辑)来确定是否可以取消订单。或者 b) 我实现 order.CanBeCancelledOnline(Contract contract) 并且逻辑保留在 Order 类中。我想你会倾向于 b) 作为最好的方法?
    • 如果订单与客户合同相关,那么它可能隐含地引用了该合同。所以这是第三种选择(如果有效,我会更喜欢)
    • 是的,我猜你可能会这么说!但是,如果出于讨论的目的 - 无法从 Order 对象中获取合同,您是否仍然更喜欢选项 b)?
    • 是的。绝对地。情报仍在 Order 对象中。
    【解决方案3】:

    您还可以使用 POCO 的扩展方法来包装您的 bll 方法。 所以你可以继续使用你当前的bll。 在 c# 中类似:

    public static class OrderBusiness <- everything must be static, class and method
    {
      public static bool CanBeCancelledOnline(this Order order) <- notice the 'this'
      {
        logic ...
    

    现在你可以做 order.CanBeCancelledOnline()

    【讨论】:

      【解决方案4】:

      这可能取决于您的应用程序的复杂性,并且确实需要一些经验来判断。简短的回答是,如果您的项目不仅仅是一个非常简单的项目,那么您最好将您的逻辑放在域类中。

      更长的答案:

      如果您将逻辑放在服务层中,您将有效地遵循transaction script pattern,并以anaemic domain model 结束。这可能是一条有效的路线,但它通常最适用于简单和小型的项目。问题是事务脚本层(您的服务层)随着它的增长而变得更加难以维护。

      因此,另一种选择是创建一个包含逻辑的富域模型。将逻辑与其适用的类保持在一起是良好 OO 设计的关键部分,并且在复杂的项目中非常重要。最初通常需要更多的思考和努力,这就是为什么对于非常简单的项目,人们有时会使用事务脚本模式。

      如果您不确定要使用哪个,重构您的逻辑以将其从服务层移动到域通常不是一项太难的工作,但您需要尽早进行调用以确保工作不会太繁琐大。

      与答案之一相反,使用 POCO 类并不意味着您的域类中不能有业务逻辑。 POCO is about not applying framework specific structures to your domain classes,例如特定于特定 ORM 的方法和接口。具有应用业务逻辑的一些功能的类显然仍然是普通旧 CLR 对象。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-04-15
        • 1970-01-01
        • 2010-12-20
        • 2013-09-14
        • 2012-03-08
        • 1970-01-01
        • 1970-01-01
        • 2011-04-26
        相关资源
        最近更新 更多