【问题标题】:My entities have only setters and getters but no methods - design failure -我的实体只有 setter 和 getter,但没有方法 - 设计失败 -
【发布时间】:2012-07-25 08:55:15
【问题描述】:

我读过一次:

“除非你有充分的理由,否则不要将实体作为 getter 和 setter 的包,并将它们的方法放在另一层”

我的客户、订单、...对象只是从 SqlDataReaders 获取数据。他们只有 getter 和 setter。

我的第一个问题是,当有人在实体中实现方法时,遵循哪种设计方法?这些方法在做什么?

【问题讨论】:

  • 听起来您正在使用对象作为数据模型。这在大多数情况下都很好。您的一般建议是帮助避免称为上帝对象的反模式,其中一个对象包含所有事物的每条逻辑。
  • 听起来更像是codereview.stackexchange.com的问题

标签: c# architecture poco


【解决方案1】:

这种思维方式来自领域驱动设计社区。​​p>

在 DDD 中,您创建一个域模型来捕获用户请求的功能。您将实体设计为具有功能和所需的数据。您将它们组合在一起,并且您有单独的类负责构建(工厂)和查询(存储库)。

如果您只有 getter/setter,则您有一个“贫血域模型”。 Martin Fowler 在article 中写到了它。

贫血域模型的问题在于,您有将数据库映射到对象的开销,但没有它的好处。如果您不将实体用作真正的域模型,为什么不直接使用 DataTable 或其他东西来存储数据并将业务逻辑保留在单独的函数中? Anemic Domain 模型是一种应该避免的反模式。

您还提到您自己映射实体。 This blog 解释了为什么使用对象关系映射工具真的很有帮助。如果您将实体框架与 Code First 方法一起使用,您可以编写一个包含数据和功能的干净域模型,并将其映射到您的数据库,而不会有太多麻烦。然后,您将拥有两全其美。

【讨论】:

    【解决方案2】:

    当您将方法作为模型的一部分时,您应该只包含模型特定类型的逻辑。例如,考虑一个银行账户:

    public class Account {
       public AccountId Id { get; set; }
       public Person Customer {get; set; }
    
       public void Credit(Money amount) { ... }
       public void Debit(Money amount) { ... } 
    
    }
    

    Credit 和 Debit 是特定于模型的逻辑(您不会在应用程序的其他任何地方找到它们),应该封装在 Account 类中。

    您还提到您在模型类中使用 SqlDataReader 从数据库中获取数据。这是一个很大的反模式。以下是您会遇到的一些问题:

    1. 违反单一职责原则 - 模型现在负责表示数据并从数据库中获取数据。
    2. 查询模型中的孩子怎么样?它变得一团糟。
    3. 您将无法轻松更改数据访问权限。

    保持模型精益。将数据访问逻辑放在存储库中,即 AccountRepository。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多