Java中的通用存储库

时间:2015-02-24 08:48:47

标签: java android generics dry

我们说我有这堂课:

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);  }
}

由于我有更多种类的实体,而不仅仅是Photo,我希望有一个通用的存储库,我可以通过任何类型的Dao。

我尝试使用Class<? extends AbstractDao<?, ?>>作为构造函数的参数,但编译器说de deo方法无法解析。这些方面的东西:

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);  }
}

我尝试过使用type参数,没有它,以及其他一些排列,没有运气。 有没有办法在Java中做到这一点?

感谢。

1 个答案:

答案 0 :(得分:5)

您必须为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> { .. }