让我说我有一些通用接口
public interface Service<T> {
T getData();
}
public interface ResponseBuilder<T> {
void build(T response);
}
和一些使用这些接口的通用类
public class Orchestrator<T> {
private Service<T> service;
private List<ResponseBuilder<T>> responseBuilders;
public Orchestrator(Service<T> serviceImpl, List<ResponseBuilder<T>> buildersImpl){
this.service = serviceImpl;
this.responseBuilders = buildersImpl;
}
public void execute() {
T response = service.getData();
responseBuilders
.stream()
.map(builder -> builder.build(response))
.forEach(data -> storageUtil.upload(data));
}
}
当客户开发人员要使用这些API时,我如何强制他/她在这些通用接口的具体实现中传递相同的类型,以避免类型不匹配的异常。
在未指定Orchestrator类型的情况下创建的实例可以采用不同的类型作为参数 例如:-
public class App{
public static void main(String[] args){
ResponseBuilder<String> response1 = new SomeImpl(); // type STRING
Service<Integer> service = new SomeServiceImpl(); // type INTEGER
// completely valid and compilable code, will throw ex at runtime
Orchestrator orch = new Orchestrator(service, Arrays.asList(response1));
}
}
什么是更好的设计?
答案 0 :(得分:0)
禁止使用原始类型。
Orchestrator orch = new Orchestrator(service, Arrays.asList(response1));
那应该产生警告。不要发出警告。
Orchestrator<T> orch = new Orchestrator<T>(service, Arrays.asList(response1));
答案 1 :(得分:0)
我认为您正在做的事是正确的,但是只缺少正确使用通用功能的部分。
您没有使用Orchestrator T的类型。
当您接受其他对象的通用类型实例时,可以验证它们是否具有相同的通用类型。
例如,在类Orchestrator中,您应该执行以下操作:
let poly_shapes = $('#clouds_1_')
此处的不匹配类型将在编译时引发错误。如果Orchestrator实例的类型定义为
,则此方法有效public class Orchestrator<T> {
private Service<? extends T> service;
private List<? extends ResponseBuilder<? extends T>> responseBuilders;
public Orchestrator(Service<? extends T> service, List<? extends ResponseBuilder<? extends T>> buildersImpl){
this.service = service;
this.responseBuilders = buildersImpl;
}
}
此外,如果我们只有几种类型的通用可能性,那么最好的方法是使Orchestrator 抽象,并且扩展它的类应指定类型。例如,
= new Orchestrator<String>(....);
然后,使用一些具体的实现实例化Orchestrator,这在某种意义上不是通用的:
public class StringOrchestrator extends Orchestrator<String> {
public StringOrchestrator(Service<? extends String> service,
List<? extends ResponseBuilder<? extends String>> buildersImpl) {
super(service, buildersImpl);
}
}