Basically all modern object-oriented programming language doesn’t support multi-inheritance. While this is a good constraint to avoid design smells, it imposes some limitation on some use cases.
For example, let’s say we want to be able to code a Repository design pattern implementation which could be both use a given data mapper and also be specialized in derived classes by overridding polymoprhic methods, but provide such specializations without coupling them to a particular data mapper.
See the following code to get convinced about it’s not possible to specialize repositories this way and with simple inheritance:
Summary of issues using pure inheritance:
Inheritance is the approach to share common rules and functionalities across all your repository implementations.
Thus, you get stuck with a concrete data mapping technology.
Solution
Main goal is to implement repositories which share a lot in common, but these common concerns shouldn’t be coupled to a concrete data mapping technology.
There should be (at least) two repository implementations
That’s it! There should be two repository implementations:
One will be agnostic to data mapping technology. That is, it’ll be the one that will implement concerns that will be absolutely common to all repositories across your solution.
Second will be the one coupled to a specific data mapping technology.
Both #1 and #2 will build an agnostic repository. Let’s see a code sample in C# to learn how to achieve the whole goal with a pratical example (also check the comments
within the whole code sample):
Furthermore, you would use some dependency injection/inversion of control container framework to configure that any derived class of AgnosticRepository<T> should inject the EntityFrameworkRepository<T> implementation. That is, you would inject an agnostic repository as follows:
Did you find some problem on this design pattern, or do you want to improve it?
Go to our GitHub repository and open an issue, and let's talk about it!