前提:在我的项目中,我有两个通用类型的接口,分别定义了Request和Response。处理请求以产生响应,因此每个响应都是基于请求构建的。处理器接口处理构建相应响应的请求。
代码:请求和响应接口是:
interface Request<T1>
和
interface Response<T2>
分别是T2
和T1
代表通用请求和响应类型(为了清楚起见,我故意用不同的名称调用它们)。
现在,由于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) {
...
}
}
问题:以上代码是否过度设计?是否有一种简化的方法来表示互补输入输出对象的元组?
答案 0 :(得分:1)
除非我完全误解了你的问题,否则你不会 - 也不应该 - 使用泛型来解决这类问题。使用多态性和/或组合将更合适。例如,如果您需要在响应中集成请求的副本(几乎没有必要但可以想到),那么您可以在响应类中添加对请求对象的引用。
从技术上讲,可以使用类型定义对Request
对象的引用;但是,你不应该这样做,因为它总是一个Request
对象(基类或派生的子类),而不是某种任意类,它可能随着响应的每个实例而改变。
当每个引用对象的类型完全不同时使用泛型(例如,List <String>
或List<Request>
:String
和{{{之间没有子类关系1}} object)或者当使用多态时不够时,因为你在子类中定义了一个或多个新的虚函数,而这些函数在超类中不存在。
将Request
构建为基于Response
,因为处理Request
以产生Request
绝对不是您要去的方式{{1}接口就是对此的见证。
答案 1 :(得分:1)
我认为您不需要在类型定义中链接Request
和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) {
...
}
}
足够吗?实际上我不确定你是否需要通用。
答案 2 :(得分:0)
有一个用例,其中有一个通用的请求/响应(或者至少是请求)。如果请求被广泛包含响应类型,则以下调用是“typesafe”
public <messy define of T> T sendRequest(Request<T> request)
现在,该方法的用户将看到“typesafe”请求 - 响应调用。我只调用“类型安全”,因为该方法的实现可能必须将响应转换为T,因此ClassCastExceptions在理论上是可行的,但在大多数情况下,它们将被视为应用程序逻辑错误。
我不会将请求/响应的实际字段放在其他字段中,只需使用泛型类型信息进行“类型安全”请求 - 响应调用。