简体   繁体   English

Generics 混乱

[英]Generics confusion

Apologies for the generic title, I can't really think of a way to explain this.通用标题道歉,我真的想不出一种方法来解释这一点。

I'd like to model a scenario where a system provides facilities to users, which have associated policies applied to requests against those facilities.我想 model 一个系统向用户提供设施的场景,这些设施具有应用于针对这些设施的请求的相关策略

public interface Facility {
    public List<Policy> getPolicies();
}
public interface Policy {
    public void apply(Facility facility, Request request);
}
public interface Request {

}

But a request can only be sensible for a particular type of facility, and a policy can really only apply to a type of facility and a type of request specific to that type of facility.但是请求只能对特定类型的设施有意义,并且策略实际上只能适用于一种类型的设施和特定于该类型设施的请求类型。

public interface Facility<F extends Facility<F>> {
    public List<Policy<F, ? extends Request<F>>> getPolicies();
}
public interface Policy<F extends Facility<F>, R extends Request<F>> {
    public void apply(F facility, R request);
}
public interface Request<F extends Facility<F>> {

}

But I'd also like to be able to specify policies overall, such that they can apply to any Facility supertype.但我也希望能够总体上指定策略,以便它们可以应用于任何 Facility 超类型。

public interface Facility<F extends Facility<F>> {
    public List<Policy<? super F, ? extends Request<F>>> getPolicies();
}

But in reality you're only ever going to want to query the policies that apply to a particular type of request for the facility.但实际上,您只想查询适用于特定类型的设施请求的策略。

public interface Facility<F extends Facility<F>> {
    public <R extends Request<F>> List<Policy<? super F, R>> getPolicies();
}

My problem is now I'm so confused with all the generics and I'm not able to even create a policy class that applies to all Facilities, which would be something like this, if it were legal我的问题是现在我对所有 generics 感到非常困惑,我什至无法创建适用于所有设施的策略 class,如果合法的话,这将是这样的

public class GeneralPolicy implements Policy<T extends Facility<T>, Request<T>>

How do I go about making it possible to associate types of facility, policy and request in such a way that makes sense according to the description above?我如何以根据上述描述有意义的方式关联设施、策略和请求的类型? I'm sure people will ask for clarification, I've battled with this long enough that I'm probably not explaining something, or completely missing an obvious point.我敢肯定人们会要求澄清,我已经与这个斗争了足够长的时间,我可能没有解释什么,或者完全错过了一个明显的点。

If I read this correctly, what you really want to do is get all the policies that work for R.如果我没看错的话,您真正想做的是获取适用于 R 的所有策略。

public interface Facility<F extends Facility<F>> {
    public <R extends Request<F>> List<Policy<? super F, R>> getPolicies();
}

Unfortunately, thanks to type erasure, you can't.不幸的是,由于类型擦除,您不能。 At runtime, the compiler doesn't know what R is.在运行时,编译器不知道 R 是什么。

What you can do, however, is pass the class in:但是,您可以将 class 传递到:

public interface Facility<F extends Facility<F>> {
    public <R extends Request<F>> List<Policy<? super F, R>> getPolicies(Class<R> requestClass);
}

Then Policy would need to return its request type as well:然后 Policy 也需要返回其请求类型:

public interface Policy<F extends Facility<F>, R extends Request<F>> {
    public void apply(F facility, R request);

    public Class<R> getRequestClass();
}

The implementation of facility can then though the list of available policies, check if the policy's request type matches the actual requested type, and return that subset.然后,设施的实现可以通过可用策略列表,检查策略的请求类型是否与实际请求的类型匹配,并返回该子集。

For global policies, the policy could return Request.class.对于全局策略,该策略可以返回 Request.class。 For specific ones, MyRequest.class.对于特定的,MyRequest.class。

Furthermore, I'd say that Facility (at least the way you have it there) doesn't need to be genericized, and it'll make the code much simpler.此外,我会说 Facility (至少你在那里拥有它的方式)不需要被泛化,它会使代码更简单。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM