1

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

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

interface Request<T1>

interface Response<T2>

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

现在,由于 T2是一个请求,而 T1是一个响应,所以上面的代码演变为:

interface Request<T1 extends Response>

interface Response<T2 extends Request>

注意: Request 和 Response 接口不共享任何继承关系 - 上面的代码只打算传达的是: Request 只使用其他类型,即 Response。

现在,考虑 Request 接口:由于 Response 再次被键入,并且由请求构建的响应将绑定到原始请求类型,因此,上面的代码演变为:

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

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

现在,处理器接口定义为:

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) {
    ...
    }
}

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

4

3 回答 3

1

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

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

当每个引用对象的类型完全不同时(例如,aList <String>或 a :a和对象List<Request>之间没有子类关系),或者由于定义一个或多个新对象而使用多态性不够用时,您可以使用泛型子类中不存在于超类中的虚函数。StringRequest

Response基于a 构建 aRequest因为 aRequest被处理以产生 aResponse绝对不是要走的路,您当前的Processor界面就是证明。

于 2013-02-01T08:08:20.260 回答
1

我认为您不需要在类型定义中链接 theRequest和 the 。Response他们被Processor. 是不是像

interface Requestable {
    ...
}

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

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

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

充足的 ?实际上,我不确定您是否需要通用。

于 2013-02-01T11:08:54.140 回答
0

在一个用例中,有一个通用的请求/响应(或者至少是请求)很有用。如果将请求生成为包含响应类型,则以下调用是“类型安全的”

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

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

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

于 2015-05-27T11:04:00.740 回答