问题描述
前提:在我的项目中,我有两个分别定义请求和响应的一般类型接口。处理请求以产生响应,因此每个响应都基于请求构建。处理器接口处理请求以构建相应的响应。
代码:请求和响应接口为:
界面请求< T1>
和
界面响应< T2>
,其中 T2 和 T1 代表通用的请求和响应类型(为了清楚起见,我刻意地用不同的名字来调用它们)。
现在,由于T2 是一个请求,而T1 是一个响应,所以上面的代码演变为:
接口请求< T1扩展响应>
和
界面响应< T2 extends Request>
请注意:Request和Response接口不共享任何继承关系 - 上面的代码只有打算进行沟通的是:请求只有一些其他类型 - 即响应。
现在,考虑请求界面:由于响应再次类型化,并且由请求构建的响应将与原始请求类型绑定,因此,上述代码演变为:
接口请求< T1扩展响应<扩展请求< T1>>>
和
接口响应< T2扩展请求<扩展Response< T2>>
现在,处理器界面被定义为:
接口处理器< R1扩展请求< R2>,R2扩展响应< R1>>> {
R2过程(R1请求);
具体类:
请求实现:
class ConcreteRequest implements Request< ConcreteResponse> {
ConcreteResponse响应;
...`
}
响应实施:
class ConcreteResponse实现Response< ConcreteRequest> {
ConcreteRequest请求;
...
}
处理器执行:
class ConcreteProcessor实现了Processor< ConcreteRequest,ConcreteResponse> {
ConcreteResponse进程(ConcreteRequest请求){
...
}
}
问题:上述代码是否过度设计?是否有简化的方法来表示一个互补的输入输出对象的元组?除非我完全误解了你的问题,你不 - 也不应该 - 为这类问题使用通用的。使用多态性和/或组合将会更合适。例如,如果您需要在响应中集成请求的副本(几乎不必要但可想而知),那么您可以在响应类中添加对请求对象的引用。
Request 对象的引用;然而,你不应该这样做,因为它总是一个 Request 对象(基类或派生子类),而不是某种可以改变的任意类每个引用对象的类型完全不同(例如, List< String> 或 List< Request> : String 和a之间没有子类关系请求对象),或者当多态性的使用不够充分时,因为您在子类中定义了一个或多个新的虚函数,这些虚函数不存在于超类中。
建立一个 Response 以基于 Request ,因为 Request 处理得到一个响应绝对不是要走的路,当前的 Processor 界面是对此的证明。
Premise: In my project I have two generically typed interfaces defining Request and Response respectively. A request is processed to yield a response, hence every response is built based on a request. A Processor interface processes a request to build the corresponding response.
Code: The request and response interfaces are:
interface Request<T1>
and
interface Response<T2>
respectively, where T2 and T1 represent generic request and response types (I am deliberately calling them by different names for clarity).
Now, since T2 is a Request, and T1 is a response, so the above code evolves to:
interface Request<T1 extends Response>
and
interface Response<T2 extends Request>
Note that: Request and Response interfaces do not share any inheritance relationship - what the above code only intends to communicate is: Request is typed with only some other type which is-a Response.
Now, consider the Request interface: since Response is again typed, and the response built out of a request will be tied to the original request type, hence, the above code evolves to:
interface Request<T1 extends Response<? extends Request<T1>>>
and
interface Response<T2 extends Request<? extends Response<T2>>
Now, the Processor interface is defined as:
interface Processor<R1 extends Request<R2>, R2 extends Response<R1>> { R2 process(R1 request); }
Concrete classes:
Request implementation:
class ConcreteRequest implements Request<ConcreteResponse> { ConcreteResponse response; ...` }
Response implementation:
class ConcreteResponse implements Response<ConcreteRequest> { ConcreteRequest request; ... }
Processor implementation:
class ConcreteProcessor implements Processor<ConcreteRequest, ConcreteResponse> { ConcreteResponse process(ConcreteRequest request) { ... } }
Question: Is the above code over-designed? Is there a simplified way to represent a tuple of complementary input-output objects?
Unless I've totally misunderstood your question, you don't - and shouldn't - use generic for this kind of problem. Using polymorphism and/or composition will be much more appropriate. For example, if you need to integrate a copy of the request in the response (hardly necessary but thinkable) then you can add a reference to a request object in your response class.
Technically, this reference to a Request object could be defined using a type; however, you shouldn't do that because it will always be a Request object (either a base class or a derived subclass) and not some kind of arbitrary class that could change with each instanciation of a response.
You use generic when the type of each referenced object is totally different (for example, a List <String> or a List<Request>: there is no subclassing relationship between a String and a Request object) or when the use of polymorphism will not be sufficient because you are defining one or more new virtual functions in a subclass that are not present in the superclass.
Building a Response to be based on a Request because a Request is processed to yield a Response is definitely not the way to go and your current Processor interface is a testimony to that.
这篇关于互补的泛型类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!