实体是否应该对其DAO有所了解?

时间:2010-08-24 13:58:43

标签: nhibernate domain-driven-design dao

我有机会将NHibernate引入我的小组,将其与一些新组件一起使用,这些组件将被添加到遗留应用程序中。我正在尝试使用带有NHibernate的DAO模式来解决这个问题,并且遇到了一个架构问题。

在我的虚构的示例中,假设我有CarDAO和Car实体:

public interface CarDAO {
    Car FindById(int id)
    ... // everything else
}

public interface Car {
    ... various properties and methods
}

我需要能够将汽车转换为右侧驾驶。由于这将是一个非常复杂的操作,我需要执行存储过程。我不清楚ConvertToRightHandDrive()方法应该去哪里。

将方法放在Car上,让它调用CarDAO上将执行存储过程的方法是有意义的。这是我不清楚的地方:

  • 汽车应该参考CarDAO并致电CarDAO.ConvertToRightHandDrive?
  • 是否应该有某种CarService层调用CarDAO.ConvertToRightHandDrive?
  • 如何通过汽车上的方法注入CarDAO(Car.ConvertToRightHandDrive(carDAO))
  • 其他一些选择?

也许这只是一个宗教论点,人们对一个实体是否应该提及其DAO(或任何其他DAO,就此而言)有不同的意见。我一直在搜索StackOverflow已经有一段时间了,并且已经围绕这个主题进行了几次讨论;但是,在这种特殊情况下,我会对人们的意见感兴趣。

2 个答案:

答案 0 :(得分:1)

我总是被告知考虑它的方式是实体应尽可能少,并且各种对象应该对实体执行操作。实体本身不应该知道DAL或他们丢失数据存储无知

因此,在这种情况下,可能依赖于CarManager的{​​{1}}(或类似)应该使用CarDAO方法。

执行复杂操作的ChangeToRightHandDrive(Car)的另一个好处是你不依赖于存储过程 - 这几乎肯定是一个宗教问题,但我更喜欢我的代码中包含所有逻辑而不是依赖SP(有一些例外,但通常只有大型集合)。这意味着,如果您更改为另一个CarManager(例如XML),则无需在DAL中重新实施SP - 否则,您最终会在您的内嵌中嵌入业务逻辑DAL。

答案 1 :(得分:1)

我的意见是Car应该不了解CarDAO。这样可以保持域模型的清洁,并允许您在不影响Car类的情况下更改后端。

如果您需要调用存储过程将汽车转换为右侧驱动器,我喜欢选择使用CarDAO.ConvertToRightHandDrive(Car car)方法然后使用类似CarService类的方法来隐藏依赖项在来自任何呼叫者的CarDAO上(即CarService类具有相同的方法,只能将呼叫转发到CarDAO)。

正如你所提到的,人们肯定会对这类事情持不同意见,但在开始攻击之前,总是值得仔细考虑依赖关系和耦合。