I am doing some research on SOLID principal, and found some issues in implementations of Repository pattern. I am going to explain each and every problem, Please correct me if I am wrong.
Problem 1
Repository Pattern Breaks Single responsibility principle (S)
Let say we have a interface which define as
public interface IRepository<T> where T: IEntity
{
IEnumerable<T> List { get; }
void Add(T entity);
void Delete(T entity);
void Update(T entity);
T FindById(int Id);
}
Clearly it violates the single responsibility principle because when we implement this interface, In a single class we are putting Command and Query both. and this not expected.
Problem 2
Repository Pattern Breaks Interface segregation principle (I)
Say We have 2 Implementation of the above Interface.
First Implementation
CustomerRepository : IRepository<Customer>
{
//All Implementation
}
Second Implementation
ProductRepository : IRepository<Product>
{
//All Implementation except Delete Method. So Delete Method Will be
void Delete (Product product){
throw Not Implement Exception!
}
}
And as per ISP "No client should be forced to depend on methods it does not use." So we saw that clearly it also violates the ISP.
So, My understanding is Repository pattern does not follow SOLID principal. What do you think? Why should we choice this type of pattern which violates the Principal? Need your opinion.
Clearly it violates the single responsibility principle because when we implement this interface, In a single class we are putting Command and Query both. and this not expected.
That's not what Single Responsibility Principle means. SRP means that the class should have one primary concern. The primary concern of a repository is to "mediate between the domain and data mapping layers using a collection-like interface for accessing domain objects" (Fowler). That's what this class does.
Repository Pattern Breaks Interface segregation principle
If that bothers you, then simply provide another interface that doesn't include the method you're not going to implement. I personally wouldn't do that, though; it's a lot of extra interfaces for marginal benefit, and it clutters the API unnecessarily. A NotImplementedException
is very self-explanatory.
You're going to find that there are a lot of rules, laws or principles in computing that have exceptions, and some that are outright wrong. Embrace the ambiguity, learn to write software from a more practical perspective, and stop thinking about software design in such absolute terms.