Универсальный репозиторий на Java


Допустим, у меня есть такой класс:

public class PhotoRepository  {
    private PhotoDao db;

    PhotoRepository(PhotoDao dao) {
        db = dao;
    }

    public void save(List<Photo> photos) { db.insertOrReplaceInTx(photos); }
    public List<Photo> all()  { return db.loadAll(); }
    public Photo get(Long id) { return db.load(id);  }
}

Поскольку у меня есть больше видов сущностей, а не только фото, я хотел бы иметь универсальный репозиторий, где я могу передать любой вид Dao.

Я пробовал использовать Class<? extends AbstractDao<?, ?>> в качестве параметра конструктора, но компилятор говорит, что методы de dao не могут быть разрешены. Что-то вроде этого:

public class Repository<T>  {
    private Class<? extends AbstractDao<T, ?>> db;

    Repository(Class<? extends AbstractDao<T, ?>> dao) {
        db = dao;
    }

    public void save(List<T> items) { db.insertOrReplaceInTx(items); }
    public List<T> all()  { return db.loadAll(); }
    public T get(Long id) { return db.load(id);  }
}

Я пробовал с параметром типа и без него, и несколько других перестановок, без удачи. Есть ли способ сделать это в Ява?

Спасибо.

1 2

1 ответ:

Вы должны ввести второй параметр типа для класса Repository, который будет представлять dao, потому что Class<? extends AbstractDao<T, ?>> неверно.

Назовем этот параметр второго типа D. Это всегда должен быть подкласс AbstractDao, параметризованный типом объекта, с которым вы хотите работать (т. е. типом T)

public class Repository<T, D extends AbstractDao<T>>  {
    private D db;

    Repository(D dao) {
        db = dao;
    }

    public void save(List<T> items) { db.insertOrReplaceInTx(items); }
    public List<T> all()  { return db.loadAll(); }
    public T get(Long id) { return db.load(id);  }
}

Тогда вы сможете создать экземпляр Repository с помощью:

Repository<Photo, PhotoDao> repo = new Repository<>(new PhotoDao());
Обратите внимание, что я предполагаю, что PhotoDao определяется как:
class PhotoDao extends AbstractDao<Photo> { .. }