1

I found the following definition of Repository Pattern:

Repositories are classes or components that encapsulate the logic required to access data sources. They centralize common data access functionality, providing better maintainability and decoupling the infrastructure or technology used to access databases from the domain model layer.

and the following definition for Strategy Pattern:

The main feature of this pattern is that the client has a set of algorithms in which a specific algorithm will be selected for use during runtime. These algorithms are interchangeable between them.

They sound so similar except that repository is specifically used for data sources whereas strategy is more general but other than that aren't they the same; better put, is the repository pattern a more specified implementation of the strategy pattern or are there differences that I'm overseeing?

1
  • 2
    Some historical context: unlike Repository, the Strategy pattern is one of the classic patterns from the 1994 Design Patterns book, and all of the patterns in there address problems that are expressed in terms that are somewhat more generalized in comparison to the problems addressed by these sort of enterprise-y patterns (such as Repository). These are more about "here's some common solutions to problems you'll specifically encounter in enterprise applications". So in some sense, you're not wrong. Apr 6 at 14:58

2 Answers 2

3

The Repository Pattern is often implemented in a way so that the Repository uses the Strategy Pattern – but this not a core aspect of that Pattern.

The point of a Repository (in the Domain-Driven Design sense) is to provide an object that encapsulates the data access logic, so that the programmer can use the Repository as if it were an in-memory collection. This description involves objects, but does not rely on other OOP concepts such as interfaces or inheritance. If the Repository is related to one of the classic GoF OOP design patterns, it might be a Factory pattern since the repository creates the Entity objects when returning results from a query.

Instead of just letting a Repository behave as if it were an in-memory collection, it's possible to create a Repository interface so that you can have multiple implementations of the Repository in your code. There might be implementations that encapsulate different database technologies, for example a Postgres-Repository and a CouchDB-Repository, or an in-memory-Repository for use in unit tests. Then, each of these implementations could also be interpreted as a Repository-Strategy.

Instead of saying that a Repository necessarily is a Strategy, I'd rather say that it harmonizes very well with the Strategy pattern. Some articles such as the MSDN architecture suggestions that you quoted do suggest the use of these interfaces, and it is a de-facto best practice, and it is almost always done when using the Entity Framework. For example, such interfaces aid with dependency inversion and testability. The MSDN article notes:

As noted in an earlier section, it's recommended that you define and place the repository interfaces in the domain model layer so the application layer, such as your Web API microservice, doesn't depend directly on the infrastructure layer where you've implemented the actual repository classes.

So these interfaces aren't strictly necessary for using the repository pattern, but introducing these interfaces and combining Repositories with the Strategy Pattern definitely has some advantages.

Another way to look at this is that the Strategy pattern is a very generic behavioural pattern. Strategies are ubiquitous and sometimes barely worth mentioning when they are “just an interface”. From that viewpoint, a Repository interface is an application of the general Strategy idea to the specific problem domain of data access.

1

The strategy pattern and repository pattern are in my opinion wildly different and I don't quite see the similarity that you seem to be pointing out; but I do acknowledge that it's easy to miss nuances in abstractions and design patterns when you don't quite understand their practical use cases, and it's also relatively common for the two patterns to be used in conjunction with one another.

Putting it into my own words, the repository pattern's use case could be described as:

I have some data over there. I would like to have a reusable component that provides anyone who needs it access to this data.

Compare this to a strategy pattern, whose use case in simple terms would more be like:

There are many ways to skin a cat. I want to be able to write my code in a way that someone can dynamically choose how they want their particular cat skinned, without my own code needing to know about or account for all the ways in which a cat can be skinned.

Pretty much inherently, a strategy pattern implies that there are multiple implementations of the same base type/interface, and that they can be used interchangeably.

A repository pattern however does not imply that there is more than one implementation of the data access type (i.e. your repository). Maybe in your particular use case there are multiple implementations, or you might introduce a repository interface here for ulterior reasons (good practice, mockability, ...); but that is unrelated to the repository pattern itself.

It is possible to do both at the same time. You might have a codebase where your data persistence is implemented using varying technologies, which means that you have multiple possible implementations of a given repository interface (e.g. an Entity Framework repository, a Dapper repository, a MongoDb repository, a file storage repository, ...). These implementations can be argued to be strategies.

2
  • Typically repository interfaces are introduced to facilitate testing. A mock, stub or fake repository for unit testing is a valid implementation of the interface. I'm not sure if "(the) repository pattern however does not imply that there is more than one implementation of the data access type (i.e. your repository)" is necessarily an accurate statement if you write unit tests. Apr 6 at 14:37
  • @GregBurghardt: If we're talking about good practice development in general, I agree with the general good practice advice to use interfaces to enable mockability and to test your code. However, that doesn't mean that this falls under the denominator of what the repository pattern by itself is.
    – Flater
    Apr 6 at 14:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.