Object-oriented – Repository pattern implementation that knows nothing about the database table and column names

design-patternsdomain-driven-designobject-orientedPHPrepository

I've seen around the Internet and Github, implementations for the design pattern Repository that knows about database table and column names. I was think, if I want to work with the database as a plugin, that I can unplug and plug another respecting Open/Closed for the rest of my code, my repository should not know about the column names of the database I'm using. So how to implement this pattern in a way that it can transform the result from the database into a Entity of my domain, without knowing about the database table and column names?

As my main language is PHP, I saw that in Doctrine\ORM you can easily pass different yamls or xmls config files, mapping the column names to property names on the Entity, but… I cant be a hostage of a library implementation, if I want to implement raw PDO, or any other library for my repositories that doesn't make this hydration out-of-the-box, my implementation should do, so how?

Update
Illustration

Update 2
Please, take a look at: http://leocavalcante.github.io/patterns/2014/07/11/repository-pattern-and-database-schema.html

Best Answer

The purpose of the repository is to provide an adapter around the database. It "knows about the database" so the rest of your code doesn't have to.

So it seems quite reasonable to me that if you change your database schema, you'll have to change (or altogether replace) your repositories. The point is that you only have to replace the repositories, because the implementation is hidden from the application by the interface.

If you have lots of aggregates and a repository for each of them, so replacing them wholesale is hard, you might be able to get help from an ORM, depending on the technologies you're using. A generic Repository<T> seems to be pretty common in C#, for example.

Of course, even if you're using an ORM, there still has to be some code, somewhere, which knows about the database schema. But this way it's usually tucked away in an XML mapping file (which of course has its own advantages and disadvantages).


Edit in response to your comments:

I don't really see what you're trying to achieve. In your design, it looks like the 'Hydration' objects take on the responsibility of communicating with the database and returning a domain object. So if you change your database schema, you still have to change all the Hydration objects. Your proposal does not solve your perceived problem: there has to be some code somewhere which knows about the database schema.

But your design is so much more complicated: there's an extra layer (the Repository itself) which basically does nothing.

public class FooRepository
{
    private IFooHydration _fooHydration;

    public FooRepository(IFooHydration fooHydration)
    {
        _fooHydration = fooHydration;
    }

    public Foo Get(int id)
    {
        return _fooHydration.Get(id);
    }

    public void Save(Foo entity)
    {
        _fooHydration.Save(entity);
    }
}

It's much simpler to use an IRepository, and write different implementations of that for your different persistence methods. In short, the Repository is what you plug-in when you change databases.