存储库模式继续 - 类方法或存储库方法?

时间:2011-01-24 21:54:37

标签: repository-pattern

给出一个结构,比如银行账户..

class Account
{
 virtual int Id { get; set; }
 virtual int Balance { get; set; }
}

我想跟踪完成的交易,所以说一个简单的类......

class Transaction
{
 virtual int Id { get; set; }
 virtual Account Account { get; set; }
 virtual DateTime Timestamp { get; set; }
 virtual int Amount { get; set; }
}

我们假设我想跟踪已完成的交易,这是更智能的方法吗?

interface IAccountRepository
{
 void Deposit(int account, int amount)
}

或......

class Account
{
 void Deposit(int amount)
 {
  // this one is easier, but then I have to repeat
  // myself because I need to store the Transaction
  // in the database too.
 }
}

Repository模式似乎是最具包容性的,因为它将具有工作单元/ orm / session(使用nHibernate)的句柄 - 但是使用类级方法似乎更直接,因为它更符合标准的面向对象原则'对此对象执行此操作'。

我的问题是,如果我想记录事务,那么我必须确保它们也被保存为数据库对象。使用类级方法进入第二条路径,我无法在Account类内部执行此操作,因此我最终不得不重复自己。

我的另一个选择是另一种抽象..

interface ITransactionRepository
{
 void CreateTransaction(int account, int amount);
}

哪种工作正常,它将A和B包装在一起,因为我会在TransactionRepository中找到该帐户然后执行其Deposit方法,但它并不真的觉得这是一个明智的做法。我不知道为什么,我的直觉告诉我这不是最好的方法。

这当然不仅仅适用于这一组课程 - 这是设计原则。如果你有任何想法,我想看看更多资深程序员在这种情况下会做些什么。

2 个答案:

答案 0 :(得分:1)

我建议在帐户上使用CRUD(创建,读取,更新,删除)操作的存储库模式。

interface IAccountRepository
{
  Add(Account acc);
  Remove(Account acc);
  Account GetAccountById(int account);
  Update(Account acc);
}

然后将Deposit方法放在Account类中,就像你提到的那样

class Account
{
  void Deposit(int amount)
  { 
  }
}

然后,您通过存储库访问该帐户以更新帐户

// Get the account by id
Account acc = rep.GetAccountById(23143);
// Deposit the money
acc.Deposit(21.23);
// Update if needed
rep.UpdateAccount(acc);

转换可以以类似的方式完成,但我可能会存储帐户ID,而不是Transcation中的Account实例。

class Transaction
{
 virtual int Id { get; set; }
 virtual int AccountId { get; set; }
 virtual DateTime Timestamp { get; set; }
 virtual int Amount { get; set; }
}

答案 1 :(得分:0)

您的问题是结构DB / OO不匹配引起的问题的一个很好的例子。根据我的经验,人们倾向于支持您描述的第一个选项 - 绕过帐户业务对象并使用存储库将事务存储在数据库中。

我强烈建议不要让您的数据库结构影响业务层设计。业务对象用于实现业务行为。当您从业务角度直接访问存储库以查找属于Account类的操作时,您的业务规则将最终位于奇怪的位置 - 外部 Account类。

要回答你的问题,我在这些情况下总是采用的方法如下:

  1. 遵循业务逻辑中的OO原则。根据实际流程构建您的类和交互,因此业务规则最终会达到您期望的水平。

  2. 为数据库提供面向存储的视图。我的意思是您的存储库不需要模仿业务对象的结构。例如,实现为帐户和事务执行CRUD的存储库。