补充泛型类型

时间:2013-02-01 07:09:28

标签: java oop generics typing

前提:在我的项目中,我有两个通用类型的接口,分别定义了Request和Response。处理请求以产生响应,因此每个响应都是基于请求构建的。处理器接口处理构建相应响应的请求。

代码:请求和响应接口是:

interface Request<T1>

interface Response<T2>

分别是T2T1代表通用请求和响应类型(为了清楚起见,我故意用不同的名称调用它们)。

现在,由于T2 请求,而T1 响应,因此上述代码演变为:

interface Request<T1 extends Response>

interface Response<T2 extends Request>

请注意:请求和响应接口不共享任何继承关系 - 上面的代码只打算进行通信:请求只使用其他类型的类型 - 响应。

现在,考虑一下Request接口:因为响应再次被输入,并且由请求构建的响应将与原始请求类型相关联,因此,上面的代码演变为:

interface Request<T1 extends Response<? extends Request<T1>>>

interface Response<T2 extends Request<? extends Response<T2>>

现在,Processor接口定义为:

interface Processor<R1 extends Request<R2>, R2 extends Response<R1>> {
    R2 process(R1 request);
}

具体课程:

请求实施:

class ConcreteRequest implements Request<ConcreteResponse> {
    ConcreteResponse response;
    ...`
}

响应实施:

class ConcreteResponse implements Response<ConcreteRequest> {
    ConcreteRequest request;
    ...
}

处理器实施:

class ConcreteProcessor implements Processor<ConcreteRequest, ConcreteResponse> {
    ConcreteResponse process(ConcreteRequest request) {
    ...
    }
}

问题:以上代码是否过度设计?是否有一种简化的方法来表示互补输入输出对象的元组?

3 个答案:

答案 0 :(得分:1)

除非我完全误解了你的问题,否则你不会 - 也不应该 - 使用泛型来解决这类问题。使用多态性和/或组合将更合适。例如,如果您需要在响应中集成请求的副本(几乎没有必要但可以想到),那么您可以在响应类中添加对请求对象的引用。

从技术上讲,可以使用类型定义对Request对象的引用;但是,你不应该这样做,因为它总是一个Request对象(基类或派生的子类),而不是某种任意类,它可能随着响应的每个实例而改变。

当每个引用对象的类型完全不同时使用泛型(例如,List <String>List<Request>String和{{{之间没有子类关系1}} object)或者当使用多态时不够时,因为你在子类中定义了一个或多个新的虚函数,而这些函数在超类中不存在。

Request构建为基于Response,因为处理Request以产生Request绝对不是您要去的方式{{1}接口就是对此的见证。

答案 1 :(得分:1)

我认为您不需要在类型定义中链接RequestResponse。它们与Processor相关联。不是像

那样的东西
interface Requestable {
    ...
}

class Request<T extends Requestable> {
    ...
}

class Response<T extends Requestable> {
    ...
}

class Processor<T extends Requestable> {
    Response<T> process(Request<T> request) {
        ...
    }
}

足够吗?实际上我不确定你是否需要通用。

答案 2 :(得分:0)

有一个用例,其中有一个通用的请求/响应(或者至少是请求)。如果请求被广泛包含响应类型,则以下调用是“typesafe”

public <messy define of T> T sendRequest(Request<T> request)  

现在,该方法的用户将看到“typesafe”请求 - 响应调用。我只调用“类型安全”,因为该方法的实现可能必须将响应转换为T,因此ClassCastExceptions在理论上是可行的,但在大多数情况下,它们将被视为应用程序逻辑错误。

我不会将请求/响应的实际字段放在其他字段中,只需使用泛型类型信息进行“类型安全”请求 - 响应调用。