簡體   English   中英

在使用存儲庫模式時,我應該將我的存儲庫方法放多少邏輯?

[英]How much logic should i put my repository methods when using repository pattern?

我正在與存儲庫進行一些努力。 我正在使用C#和NHibernate。 我的問題是:我的存儲庫在調用save或get之前應該做多少?

例如,我有一個用戶類,它是一個聚合根。 我想調用一個名為“register”的方法,它將添加用戶並根據業務規則設置一些默認值,並創建一些其他實體,這些實體也是“用戶”根的子部分(即地址,組等)。 我應該打電話嗎?

userRepo.Register(newUser); 

這將是(忽略明顯的問題):

Regsiter(User newUser){
 newUser.SomeProp  = "Default Data";
 Group g= new Group;
 g.SomeProp2 = "Default Data";
 newUser.Groups.Add(g);
 Session.Save(g);
 Session.Save(newUser);
}

或者我應該將注冊放在業務層中並讓它做:

Regsiter(User newUser){
 newUser.SomeProp  = "Default Data";
 Group g= new Group;
 g.SomeProp2 = "Default Data";
 newUser.Groups.Add(g);
 userRepo.Register(newUser, g);// this does session.save on both objects.
}

兩者似乎都有些錯誤。

什么是正確的方法?

編輯-------------------------------

感謝所有的回復。 我不能決定誰是最合適的,因此接受哪個答案。

通常每個人都在說將業務規則放在另一層。 這是有道理的,但我不確定組的數據調用 - 因為組不是聚合根,他們不應該有自己的存儲庫,所以我如何添加和保存它們? 在我的項目中,將一個組添加到用戶的組集合中不會自動在數據庫中創建該組; 我還需要在對象上調用session.save。 所以我把它作為userRepo.SaveGroup(g)放入用戶倉庫?

如果我在另一個層中有一個createGroup(),那么它將需要使用它自己的repo或用戶。 還是我很厚?

就個人而言,我將存儲庫模式保留為sprocs的替代品。 所以我的存儲庫會有getById(int id)save()add(DomainObject obj)等方法。

在業務層中,我有userManager.registerUser(字符串用戶名,/ * params等* /)。 這將創建域對象。 此方法只會調用數據層中的add()方法。

簡而言之,業務層是業務層,數據層是數據層。

您首先使用存儲庫模式的動機是什么? 通常,存儲庫是對象持久性邏輯的抽象。 它從(通常)數據庫中檢索項目,還處理更新,插入和刪除。

如果您正在編寫測試以檢查某些邏輯並且不想訪問數據庫,那么您需要模擬哪些對象? 通常是存儲庫。

在方案A)中,您無法測試使用正確的默認數據創建的新用戶,而無需直接訪問數據庫。 因此,我建議將所有業務邏輯保留在存儲庫之外,並采用第二種設計

確定您希望Register方法的位置,可能在UserServices類中。 您可以將對象創建委派給UserFactory。 在CreateNewUser()方法中,為用戶和Groups集合設置默認值。 然后調用UserRepository.Save(newUser)來保存數據。

// UserServices class
public void Register(User newUser)
{
  // add custom registration stuff.
  _userRepository.Save(newUser);
}

// Application code
User user = UserFactory.CreateNewUser();
_userServices.Register(user);

// UserFactory
public User CreateNewUser()
{
  // all new user, group creation
}

從您的代碼示例中,我將Register方法稱為服務操作。 作為服務操作,它將屬於服務或業務組件,而不是存儲庫。 根據Evans(DDD成名),存儲庫是存儲在數據庫中的實體的類似集合的接口。 一般的想法是,您通過存儲庫提供對實體的基本CRUD訪問,以從ORM工具等較低級別的數據訪問詳細信息中抽象出其余代碼。

對於您使用Register的示例...您的服務方法將驗證輸入,構建User對象,然后調用您的存儲庫以“添加”您的新實體到“存儲庫”(可能是一個數據庫......但也可能是其他...就你的域名而言,它無關緊要......它只是一個存儲庫。)

我看到兩個潛在的“錯誤”問題(因為你沒有真正表明你認為他們的錯誤)。

  1. 如果問題圍繞在用戶注冊方法中保存組,或者將用戶保存在組方法中,則應將這些方法分成不同的方法。 (即Register()將調用RegisterGroup()或GetGroup()

  2. 如果問題圍繞在用戶真正准備從概念上保存事物之前保存事物,那么跟蹤他們想要添加的內容並等待直到調用整個“保存”方法,然后將任何這些信息存儲到存儲中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM