【问题标题】:Should business objects contain objects or references?业务对象应该包含对象还是引用?
【发布时间】:2009-07-03 23:10:02
【问题描述】:

一个业务对象应该包含对其他对象的引用(如在 id 字段中引用另一个数据库记录)还是应该具有实际对象的实例。

例如:

public class Company
{
    public int Id { get; set; }
    public CompanyStatus Status { get; set; }
}

public class Company
{
    public int Id { get; set; }
    public int Status { get; set; }
}

【问题讨论】:

  • 请注意这里选择的语言。
  • 例子表明是C#。
  • @Anthony:你能澄清一下吗?你的两个例子有什么区别?在第二个中,“状态”是否意味着是状态表中的整数外键?
  • CompanyStatus 是一个类,是的,int Status 代表数据库中的一个外部变量。

标签: c# business-objects


【解决方案1】:

据我了解,它应该包含对接口的引用,而不是具体的类。

public class Company
{
    public int Id { get; set; }
    public ICompanyStatus Status { get; set; }
}

假设您的示例中 CompanyStatus 的具体实现是一个类而不是一个枚举。

【讨论】:

  • 过去几年我对这种方法非常满意。也许这与它允许我在运行时注入依赖项(en.wikipedia.org/wiki/Dependency_injection)这一事实有关。
  • @Rake36:为什么要引用接口而不是具体类?
  • 在某些情况下,它更可取。它允许交换实现,并有助于某些 ORM 技术。它确实更加强调了业务对象的合同。
  • @John Saunders:就像 nader 所说的,昨天的 FOR 也是如此 - 使用接口使您的代码更加灵活。我不是一个经验丰富的 OO 开发人员,但在创建任何具体实现之前强迫自己创建接口,我的代码更好地融合在一起。当我想添加不同的实现时(尤其是在使用工厂时),除了创建新的具体类之外我不需要做太多事情。业务层不知道区别。您也可以通过继承层次结构来实现这一点,但接口似乎工作得更好。
  • 如果类(例如“Car”)持有对类/接口“Engine”的引用,那么“Car”类不应该在私有字段(engineId)中包含外键吗?我问这个是因为 - 想象引擎实例将被缓存并且引擎将从缓存中删除而 Car 不是,Car 实例不应该能够重新加载它的引擎吗?这可以通过在 Car 中的属性“Engine”中延迟加载来完成,方法是检查私有引用“engine”字段(案例!)是否为 null,并使用私有 engineId int 字段(重新)创建它?!?您/任何人对此有何看法?
【解决方案2】:

当以 OO 方式创建业务层对象时,您应该直接使用对象。

在您的示例中,int Status 是否指的是存储在某处的 CompanyStatus 对象的 ID?在这种情况下,感觉更像是数据层问题。通常最好避免将数据层与业务层混在一起。

【讨论】:

  • 所以我认为 DAL 应该将 CompanyId 从数据库转换为 CompanyStatus 或实际上是 ICompanyStatus 是正确的,这是正确的吗?
  • 是的,没错。当你以这种方式分解它时,它会给你更多的灵活性来独立地改变你的 DAL 和业务层。
【解决方案3】:

如果您在谈论 C#,那么聚合一个对象意味着您正在存储对它的引用。

【讨论】:

    【解决方案4】:

    这取决于数据。有些数据应该存储为原始对象的副本,有些应该是引用。

    【讨论】:

    • 也许您可以详细说明两者应该在何时何地发生。
    猜你喜欢
    • 1970-01-01
    • 2010-09-11
    • 2011-05-07
    • 2011-02-25
    • 2010-10-30
    • 1970-01-01
    • 2011-06-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多