2011-06-29 22 views
9

El uso de ActiveRecord es posible definir una clase como esta:Active Records vs. Repository: pros y contras?

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

Si bien esto es bueno y sencillo, he encontrado mis clases se vuelven muy hinchado con una gran mezcla de lógica pasando!

El uso de un diseño en capas/dominio se puede definir de la misma clase como:

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

¿Cómo fue que emigraron de registro => diseño en capas activa?

  • validación a nivel de entidad en la incubadora Name => permanece (ableit a través de un DataAnnotation)
  • La lógica de negocio/validación de reglas (nombre único) => pasado de entidad en una nueva ContactValidator separada
  • Guardar lógica = > movido a una clase separada Repositorio patrón (también con un UnitOfWork) lógica
  • carga => movido al repositorio separado
  • Interacción con el Repositorio es a través de un nuevo ContactService (que cumplir el uso de ContactValidator, ContactRepository, UnitOfWork, etc - opuesto a lettin g la persona que llama suelta con el ContactRepository!).

Busco aprobación de los compañeros/sugerencias para este diseño en capas - No suelo fuera de diseño de tipo Active Record! Cualquier comentario apreciado.

NB - Este ejemplo es deliberadamente simple (el UnitOfWork no se usa realmente y el newing del Repository/Validator se manejaría de manera diferente).

Respuesta

2

Ambos enfoques tienen sus pros y sus contras.

Imagina que estás pasando un objeto con un estilo de registro activo a algún lugar (en el interior de BL). Puedes leerlo, puedes cambiarlo, puedes GUARDARLO. En este caso, esa pieza de BL solo se combina con la interfaz de tu entidad. Con la arquitectura en capas, debe pasar el repositorio a ese código de alguna manera. Lo pasarás explícitamente o usarás IoC-container, depende de ti.

El otro punto es que cuando tienes el concepto de repositorio, puedes definir fácilmente conceptos como we-have-a-new-object-in-repository, o one-object-has-been-deleted-from- repositorio que son básicamente notificaciones bastante útiles si está trabajando con un entorno distribuido.

6

Realmente depende de cuán compleja es la lógica de tu dominio. Por ejemplo, si estuviera escribiendo un blog simple, entonces el registro activo estará bien, la mayoría de las aplicaciones guardan y cargan datos. Su patrón de registro simple y activo es la herramienta adecuada para el trabajo.

Sin embargo, si estaba escribiendo software para una compañía naviera en la que existen muchas reglas y procesos comerciales complejos, el uso del patrón de repositorio, junto con otros patrones Domain Driven Design proporcionará un código mucho más sostenible a largo plazo.

Utilizando el diseño impulsado por dominio, utilizaría el specification pattern para lograr su validación.

0

Este artículo parece una buena descripción y sucinta de ambos: https://hashnode.com/post/which-design-pattern-do-you-prefer-active-record-or-repository-cilozoaa5016o6t53mhsdu6nu

Una cosa que me gustaría añadir es que no es sólo "registro activo es buena cuando sus necesidades son simples y persistencia repositorio es buena cuando tus necesidades de persistencia son complejas ". La elección del patrón aquí tiene mucho más que ver con cómo te sientes con respecto a la Ley de Demeter. Si quieres que partes diferentes de tu arquitectura estén completamente separadas para que alguien pueda entender una parte sin entender otra, entonces quieres la Ley de Demeter. Dicho esto, creo que, especialmente al principio de un proyecto cuando es probable que cambie la especificación, es MUY peligroso obsesionarse con este tipo de abstracción. No adivine en segundo lugar los mantenedores futuros de su proyecto, podrían ser inteligentes y deberían poder pensar en más de una cosa a la vez y si no pueden, entonces podría tener problemas más grandes que no pueden prevenirse utilizando el patrón Repositorio. .

Cuestiones relacionadas