Saltar al contenido

¿El patrón de repositorio sigue los principios SÓLIDOS?

Solución:

Claramente viola el principio de responsabilidad única porque cuando implementamos esta interfaz, en una sola clase estamos poniendo Comando y Consulta a ambos. y esto no se esperaba.

Eso no es lo que significa el principio de responsabilidad única. SRP significa que la clase debe tener una preocupación principal. La principal preocupación de un repositorio es “mediar entre el dominio y las capas de mapeo de datos utilizando una interfaz similar a una colección para acceder a los objetos del dominio” (Fowler). Eso es lo que hace esta clase.

El patrón del repositorio rompe el principio de segregación de la interfaz

Si eso le molesta, simplemente proporcione otra interfaz que no incluya el método que no va a implementar. Sin embargo, yo personalmente no haría eso; son muchas interfaces adicionales para un beneficio marginal y saturan la API innecesariamente. A NotImplementedException es muy autoexplicativo.

Descubrirá que hay muchas reglas, leyes o principios en informática que tienen excepciones y algunas que son completamente incorrectas. Acepte la ambigüedad, aprenda a escribir software desde una perspectiva más práctica y deje de pensar en el diseño de software en términos tan absolutos.

Claramente viola el principio de responsabilidad única

Solo está claro si tiene una definición muy limitada de lo que es el SRP. El hecho es SOLID viola SOLID. Los principios mismos se contradicen. SRP está en desacuerdo con DRY, ya que a menudo tiene que repetirse para separar adecuadamente las preocupaciones. LSP está en desacuerdo con ISP en algunas situaciones. OCP a menudo entra en conflicto con DRY y SRP. Estos principios no están aquí como reglas estrictas y rápidas, sino para guiarlo … trate de adherirse a ellos, pero no los trate como leyes que no se pueden romper.

Además de eso, está confundiendo el patrón de arquitectura del repositorio con un patrón de implementación del repositorio genérico muy específico. Tenga en cuenta que un repositorio genérico es diferente de un repositorio concreto. Tampoco hay ningún requisito de que un Repositorio implemente los métodos que menciona.

Sí, puede separar el comando y la consulta como dos preocupaciones separadas, pero no es necesario que lo haga para que cada una sea una sola responsabilidad. La separación de consultas de comandos es un buen principio, pero no es algo que esté cubierto por SOLID, y ciertamente no hay consenso sobre si separar las preocupaciones cae bajo la preeminencia de diferentes responsabilidades. Son más como diferentes aspectos de la misma responsabilidad. Podría llevar esto a un nivel ridículo si quisiera y afirmar que Actualizar es una responsabilidad diferente a Eliminar o que Consultar por id es una responsabilidad diferente de consultar por tipo o lo que sea. En algún momento tienes que trazar líneas y enmarcar las cosas, y para la mayoría de las personas “leer y escribir una entidad” es una sola responsabilidad.

El patrón del repositorio rompe el principio de segregación de la interfaz

Primero, está confundiendo el principio de sustitución de Liskov con el principio de segregación de interfaz. LSP es lo que viola su ejemplo.

Como dije anteriormente, no hay ningún requisito de que el Repositorio implemente ningún conjunto específico de métodos, aparte de una “interfaz similar a una colección”. De hecho, sería perfectamente aceptable implementarlo así:

public interface IRepository where...[...] IEnumerable List  get; 
public interface CustRepository : IRepository, IRepoAdd, IRepoUpdate, IRepoDelete, IRepoFind 

Ahora, opcionalmente, puede implementar cualquiera de los otros miembros sin romper LSP, aunque es una implementación bastante tonta y ciertamente no implementaría solo para evitar romper LSP.

El hecho es que probablemente no haya una buena razón por la que desee un repositorio sin eliminar. La única razón posible en la que puedo pensar sería un repositorio de solo lectura, que definiría una interfaz separada para usar una interfaz de colección de solo lectura.

Yo mismo utilizo el patrón Repository y utilicé el patrón para asegurarme de que se implementan todas las interfaces requeridas. Para esto, creé interfaces separadas para todas las acciones (IEntityCreator, IEntityReader, IEntityUpdater, IEntityRemover) e hice que el repositorio heredara todas estas interfaces. De esta manera puedo implementar todos los métodos en una clase concreta y seguir usando todas las interfaces por separado. No veo una razón para afirmar que el patrón del repositorio viola los principios SOLID. Solo necesita definir correctamente la ‘responsabilidad’ del repositorio: la responsabilidad del repositorio es facilitar todo acceso a los datos de tipo T. Eso es todo lo que hay que decir. Como se indicó anteriormente, también tengo una interfaz de repositorio de solo lectura llamada ReferenceRepository que solo incluye el IEntityReader interfaz. Todas las interfaces se definen a continuación para una copia rápida 🙂 Además de eso, también creé algunas clases concretas, incluido el almacenamiento en caché y / o el registro. Esto es para incorporar cualquier acción adicional requerida según lo establecido por el I en SOLID. El tipo IEntity se usa como una interfaz de marcador para permitir solo entidades y no algún otro tipo de objeto (debe comenzar en alguna parte).

/// 
/// This interface defines all properties and methods common to all Entity Creators.
/// 
/// The type of the entity.
public interface IEntityCreator
    where TEntity : IEntity

    #region Methods
    /// 
    /// Create a new instance of 
    /// 
    /// 
    TEntity Create();
    #endregion


/// 
/// This interface defines all properties and methods common to all Entity Readers.
/// 
/// The type of the entity.
public interface IEntityReader
   where TEntity : IEntity

    #region Methods
    /// 
    /// Get all entities in the data store.
    /// 
    /// 
    IEnumerable GetAll();

    /// 
    /// Find all entities that match the expression
    /// 
    /// exprssion used to filter the results.
    /// 
    IEnumerable Find(Expression> whereExpression);
    #endregion


/// 
/// This interface defines all properties and methods common to all Entity Updaters. 
/// 
/// The type of the entity.
public interface IEntityUpdater
    where TEntity : IEntity

    #region Methods
    /// 
    /// Save an entity in the data store
    /// 
    /// The entity to save
    void Save(TEntity entity);
    #endregion


/// 
/// This interface defines all properties and methods common to all Entity removers.
/// 
/// The type of the entity.
public interface IEntityRemover
    where TEntity : IEntity

    /// 
    /// Delete an entity from the data store.
    /// 
    /// The entity to delete
    void Delete(TEntity entity);

    /// 
    /// Deletes all entities that match the specified where expression.
    /// 
    /// The where expression.
    void Delete(Expression> whereExpression);


/// 
/// This interface defines all properties and methods common to all Repositories.
/// 
public interface IRepository  

/// 
/// This interface defines all properties and methods common to all Read-Only repositories.
/// 
/// The type of the entity.
public interface IReferenceRepository : IRepository, IEntityReader
   where TEntity : IEntity




/// 
/// This interface defines all properties and methods common to all Read-Write Repositories.
/// 
public interface IRepository : IReferenceRepository, IEntityCreator,
    IEntityUpdater, IEntityRemover
    where TEntity : IEntity



¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *