2011-06-29 46 views
9

使用ActiveRecord您可以定義這樣一個類:活動記錄與存儲庫 - 優點和缺點?

class Contact 
{ 
    private String _name; 
    public String Name 
    { 
    get { return _name; } 
    set 
    { 
     if (value == String.IsNullOrWhiteSpace()) 
     throw new ArgumentException(...); 
     else 
     _name = value; 
    } 
    } 

    public Boolean Validate() { ... /* check Name is unique in DB */ } 

    public Boolean Save() { ... } 

    public static List<Contact> Load() { ... } 
} 

雖然這是很好的和簡單的,我發現我的課變得非常臃腫邏輯事情的一個大組合!

使用分層/域設計可以定義同一類,如:

class Contact 
{ 
    [Required(AllowEmptyStrings=false)] 
    public String Name { get; set; } 
} 

class ContactService : IService 
{ 
    public List<Contact> LoadContacts() { return (new ContactRepository()).GetAll(); } 
    public Contact LoadContact(int id) { return (new ContactRepository()).GetById(id); } 
    public Boolean SaveContact(Contact contact) 
    { 
     if (new ContactValidator().Validate(contact)) 
      new ContactRepository().Save(contact); 
    } 
} 

class ContactRepository : IRepository 
{ 
    public List<Contact> GetAll() { ... } 
    public Contact GetById(int Id) { ... } 
    public Boolean Save(Contact contact) { ... } 
} 

class ContactValidator : IValidator 
{ 
    public Boolean Validate(Contact contact) { ... /* check Name is unique in DB */ } 
} 

class UnitOfWork : IUnitOfWork 
{ 
    IRepository _contacts = null; 
    public UnitOfWork(IRepository contacts) { _contacts = contacts; } 
    public Commit() { _contacts.Save(); } 
} 

是如何從活動記錄=>分層設計遷移?

    在名稱設定器
  • 實體級別驗證=>保持(通過DataAnnotation ableit)
  • 商業邏輯/規則驗證(唯一名稱)=>從實體移動到一個新的單獨的ContactValidator
  • 保存邏輯= >移動到一個單獨的存儲庫模式類(也用的UnitOfWork)
  • 負載邏輯=>移動到單獨的存儲庫
  • 與存儲庫交互是通過一個新的ContactService(其將執行使用ContactValidator,ContactRepository,的UnitOfWork的,等 - 反對lettin g調用者與ContactRepository一起鬆動!)。

我在尋找同行對這種分層設計的認可/建議 - 我通常不會在活動記錄類型之外進行設計!任何評論贊賞。

注意 - 這個例子是故意簡單的(UnitOfWork沒有被真正使用,Repository/Validator的新功能將以不同的方式處理)。

回答

2

這兩種方法各有利弊。

假裝,你正在將Active Record樣式的對象傳遞到某個地方(BL內部深處)。你可以閱讀它,你可以改變它,你可以保存它。在這種情況下,這塊BL只與您的實體界面耦合。使用分層架構,您必須以某種方式將存儲庫傳遞給該代碼。您可以明確地將其傳遞或使用IoC容器 - 由您決定。另一點是,當你有存儲庫的概念時,你可以很容易地定義像我們有一個新對象存儲庫或一個對象已被刪除的概念,如果你使用的是分佈式環境,那麼這個庫基本上是非常有用的通知。

6

這真的取決於你的域邏輯有多複雜。例如,如果我正在編寫一個簡單的博客,那麼活動記錄將會很好,大部分應用程序正在保存和加載數據。其簡單而活躍的記錄模式是該工作的正確工具。

但是,如果我爲一家航運公司編寫軟件,其中有許多複雜的業務規則和流程,那麼使用存儲庫模式以及其他Domain Driven Design模式將提供更長期可維護的代碼。

使用域驅動設計,您可以使用specification pattern來實現驗證。

0

這篇文章似乎是兩者很好地和簡潔的描述: 我想補充https://hashnode.com/post/which-design-pattern-do-you-prefer-active-record-or-repository-cilozoaa5016o6t53mhsdu6nu

一件事是它不僅僅是「活動記錄是好的,當你的持久需求很簡單和存儲庫是好的當你的持久性需求很複雜時「。這裏的模式選擇與你對德米特法的感覺有很多關係。如果你想讓你的架構的不同部分完全分離,以便某人可以理解一個部分而不理解另一部分,那麼你就需要Demeter法則。這就是說,我認爲,特別是在一個項目早期規格可能發生變化的時候,對這些抽象類型過於執着是非常危險的。不要再猜測項目未來的維護者,他們可能很聰明,他們應該能夠一次考慮多件事情,如果他們不能,那麼你可能會遇到更大的問題,這些問題無法通過使用Repository模式來預防。