And*_*eou 6 java generics class
我有这个抽象类,我已经定义了一些实现数据库操作的方法(获取行,插入,删除等)
现在我想创建将返回一些行(即整个表)的方法,但是我希望它返回相应的模型类而不是域类(它基本上与域相同但没有关系列表和其他一些东西我不需要表示层).
抽象类是
public abstract class DomainService<T extends Domain> {
protected abstract Logger getLogger();
protected final Validator validator;
protected DomainService() {
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
this.validator = factory.getValidator();
}
abstract public void insert(T object) throws ValidationException;
abstract public void delete(T object) throws EntityNotFoundException;
abstract public List<T> fetchAll();
}
Run Code Online (Sandbox Code Playgroud)
我想添加另一个方法,它将调用fetchAll()然后迭代每个项目并创建等效的模型并返回该列表.
public <K extends Model> List<K> fetchAllModels(Class<K> modelClass) {
List<T> domains = fetchAll();
List<K> models = new ArrayList<K>(domains.size());
for ( T domain : domains) {
K model = modelClass.newInstance();
models.add(model.fillIn(domain));
}
return models;
}
Run Code Online (Sandbox Code Playgroud)
忽略这是我刚刚编写问题的代码,是否可以为类中未定义的泛型添加参数.IMO一个类可以有返回其他数据类型的方法,所以它应该不是问题.在我的情况下,我传递了类,所以我可以创建模型的实例,然后使用域来填充成员.我有两个意见,
我写的那个,我在模型类中添加一个方法,从域对象创建它自己.我在想一个构造函数域对象作为参数,但我认为这是一个有点麻烦调用使用泛型构造函数(这将需要至少是反射公用事业),所以我虽然方法来填补使用默认构造函数创建实例后的详细信息.此外,模型位于更高层,我认为更高层应该使用更低层(数据库 - >域类 - >访问类(DAO) - >服务类 - > Servlet类----> JSP显示数据)
我可以向域类添加一个方法,将域转换为其模型并调用它而不必传递模型的类
public <K> List<K> fetchAllModels() {
List<T> domains = fetchAll();
List<K> models = new ArrayList<K>(domains.size());
for ( T domain : domains) {
models.add(domain.createModel());
}
return models;
}
Run Code Online (Sandbox Code Playgroud)但我觉得域类应该像数据库中的表一样干净,只有与列有关的方法.
在类上添加参数会更好吗?我只会用它来做这个方法......
任何想法评论总是欢迎
为类中未定义的泛型添加参数是否可以接受
绝对地。它一直在做。
我更喜欢你的第一个解决方案,将模型传递给方法。
但是,您真正想要的是一个从 T 创建 K 的函数。在 java8 中,这可以非常简洁地完成。
public <K extends Model> List<K> fetchAllModels(Function<T,K> func) {
...
K model = func.apply(domain);
Run Code Online (Sandbox Code Playgroud)
并说你有一个域“D”的模型“M”
public M(D domain) // constructor
Run Code Online (Sandbox Code Playgroud)
您可以将构造函数传递为func(或至少看起来如此)
service.fectchAllModels( M::new )
Run Code Online (Sandbox Code Playgroud)
如果你使用Stream,fetchAllModels()变得更简单
abstract public Stream<T> fetchAll();
public <K extends Model> Stream<K> fetchAllModels(Function<T,K> func) {
return fetchAll().map(func)
}
Run Code Online (Sandbox Code Playgroud)
然后,为什么我们甚至需要这种方法?做就是了
// fetch domains, convert each to M
Stream<M> models = service.fetchAll().map( M::new );
Run Code Online (Sandbox Code Playgroud)
所以我们可以fetchAllModels()从域中删除,并删除对模型的任何依赖。