Active Records vs. Repository - плюсы и минусы?

Используя 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(); }
}

Как он был перенесен из Active Record => многоуровневый дизайн?

  • Проверка уровня сущности в установщике имени => остается ( ableit через DataAnnotation)
  • Проверка бизнес-логики / правила (уникальное имя) => перенесено из объекта в новый отдельный ContactValidator
  • Логика сохранения => перенесена в отдельный класс шаблона репозитория (также с UnitOfWork)
  • Логика загрузки => перемещена в отдельный репозиторий
  • . Взаимодействие с репозиторием осуществляется через новую службу ContactService (которая будет обеспечивать использование ContactValidator, ContactRepository, UnitOfWork и т. Д. - в отличие от того, чтобы позволить вызывающему абоненту терять контакт с помощью ContactRepository!).

Я ищу одобрение / предложения коллег для этого многоуровневого дизайна - обычно я не занимаюсь дизайном за пределами A ctive Тип записи! Любые комментарии приветствуются.

NB - Этот пример намеренно прост (UnitOfWork на самом деле не используется, и создание репозитория / валидатора будет обрабатываться иначе).

10
задан Andrey Agibalov 24 August 2011 в 21:09
поделиться