2011-06-29 13 views
9

Korzystanie ActiveRecord można zdefiniować klasę tak:Aktywne rekordy a repozytorium - plusy i minusy?

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() { ... } 
} 

Chociaż to ładne i proste, znalazłem moje zajęcia się bardzo nadęty z dużym mieszanką logika dzieje!

Stosując konstrukcję warstwową/domeny można określić tę samą klasę, takich jak:

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(); } 
} 

Jak zostało to przeniesione z Active Record => warstwowa konstrukcja?

  • Podmiot walidacji poziom w imię seter => pozostaje (ableit poprzez DataAnnotation)
  • logika Biznes/walidacji zasada (unikalna nazwa) => przeniesiony z jednostki do nowego oddzielnego ContactValidator
  • Zapisz logiczny = > przeniesiono do oddzielnego Repository grupy typu (również z UnitOfWork) logiki
  • obciążenie => przeniesiono do oddzielnego repozytorium
  • interakcji z repozytorium poprzez nowy ContactService (który będzie wymuszał stosowanie ContactValidator, ContactRepository, UnitOfWork, etc - przeciwieństwie do lettin g dzwoniącego luźnego z ContactRepository!).

Poszukuję aprobaty/sugestii dla tego projektu warstwowego - zwykle nie projektuję poza typem Aktywnej Rejestracji! Każdy komentarz doceniony.

NB - Ten przykład jest celowo prosty (UnitOfWork tak naprawdę nie jest używany, a tworzenie repozytorium/walidatora będzie obsługiwane inaczej).

Odpowiedz

2

Oba podejścia mają swoje wady i zalety.

Udawaj, że przekazujesz obiekt w stylu Active Record gdzieś (głęboko wewnątrz BL). Możesz ją przeczytać, możesz ją zmienić, możesz ją ZAPISZ. W tym przypadku ten fragment BL jest sprzężony tylko z interfejsem twojej jednostki. Dzięki warstwowej architekturze musisz jakoś przekazać repozytorium do tego kodu. Możesz przekazać to wprost lub użyć kontenera IoC - do Ciebie.

Inną kwestią jest to, że mając pojęcie repozytorium, można łatwo zdefiniować pojęcia takie jak "mamy-nowy-obiekt-w-repozytorium" lub "obiekt-który-został-usunięty-z-" repozytorium, które jest zasadniczo całkiem przydatnym powiadomieniem, jeśli pracujesz w środowisku rozproszonym.

6

To naprawdę zależy od złożoności logiki twojej domeny. Na przykład, gdy pisałem prostego bloga, aktywny zapis będzie w porządku, głównie aplikacja zapisuje i ładuje dane. Jego prosty i aktywny wzór zapisu jest właściwym narzędziem do pracy.

Jednak, jeśli pisałem oprogramowanie dla firmy spedycyjnej, w której istnieje wiele złożonych reguł i procesów biznesowych, użycie schematu repozytorium wraz z innymi wzorami Domain Driven Design zapewni w dłuższej perspektywie znacznie więcej kodu możliwego do utrzymania.

Korzystając z projektowania opartego na domenie, można użyć narzędzia specification pattern w celu uzyskania zatwierdzenia.

0

Ten artykuł wydaje się dobrym i zwięzłego opisu zarówno: https://hashnode.com/post/which-design-pattern-do-you-prefer-active-record-or-repository-cilozoaa5016o6t53mhsdu6nu

Jedno chciałbym dodać, to to, że jest nie tylko „aktywny rekord jest dobra, gdy Twoje potrzeby Trwałość są proste i repozytorium jest dobry kiedy twoje potrzeby przetrwania są złożone ". Wybór wzoru ma o wiele więcej wspólnego z tym, jak się czujesz na temat Prawa Demeter. Jeśli chcesz, aby różne części Twojej architektury były całkowicie rozdzielone, aby ktoś mógł zrozumieć jedną część bez zrozumienia innej, to musisz wybrać Prawo Demeter. To powiedziawszy, myślę, że szczególnie wcześnie w projekcie, kiedy specyfikacja prawdopodobnie się zmieni, BARDZO niebezpieczne staje się zbyt obsesyjne na temat tego rodzaju abstrakcji. Nie zastanawiaj się nad przyszłymi opiekunami swojego projektu, mogą być sprytni i powinni myśleć o więcej niż jednej rzeczy naraz, a jeśli nie, to możesz mieć większe problemy, którym nie można zapobiec, używając wzorca repozytorium .

Powiązane problemy