简体   繁体   English

Java继承与泛型

[英]java inheritance vs generics

Little Java design question here (for what matters it is in a context of a JEE Web Application). 这里有一点Java设计问题(对于在JEE Web应用程序上下文中重要的问题)。

Let's say I have a REST API with two operations : GET and POST on the same ressources. 假设我有一个具有两个操作的REST API:在相同的资源上进行GETPOST From there, using Jackson two classes are constructed representing the request's input fields. 从那里开始,使用Jackson构造了两个类,分别表示请求的输入字段。 Those classes are different because the requests' parameters vary a little bit. 这些类是不同的,因为请求的参数略有不同。

Let's say those two classes are named GetRequest and PostRequest . 假设这两个类分别命名为GetRequestPostRequest

Those two classes contains a set of fields that are common . 这两个类包含一组通用字段 And a set of fields that belong to each class . 还有属于每个类的组字段 For instance : 例如 :

public class GetRequest {

   // common fields
   private String callerId;

   private String userId;

   // non-common fields
   private boolean withLinkedServices;

   // Constructors, egals, hasCode, toString, getters,setter etc...
}

And for class PostRequest 对于PostRequest类

public class PostRequest {

   // common fields
   private String callerId;

   private String userId;

   // non-common fields
   private List<ServicesBean> services;

   // Constructors, egals, hasCode, toString, getters,setter etc...
}

In the business layer of my application, I have to code an helper method (for each REST operations) which will fill another bean using common fields of each objects. 在应用程序的业务层中,我必须编写一个帮助程序方法(用于每个REST操作),该方法将使用每个对象的公共字段填充另一个bean。 The implementation of this method is exactly the same for the GET and POST operations. 对于GET和POST操作,此方法的实现完全相同。

The only thing that vary is that in the case of the GET operations I have to pass the GetRequest class and for the POST I have to pass the PostRequest . 唯一不同的是,对于GET操作,我必须传递GetRequest类,对于POST,我必须传递PostRequest

So my question is : 所以我的问题是:

Should I work on the data model and use inheritance or should I use Generics in my helper method ? 我应该使用数据模型并使用继承,还是应该在辅助方法中使用泛型 Which one would make more sense and be more efficient and resilient to application's future evolution (in case more operations are added on that ressources for instance) ? 哪一种方法对应用程序的未来发展更有意义,更有效,更具弹性(例如,在该资源上添加了更多操作)?

The signature of my methods is (for the helper of the POST) : 我的方法的签名是(对于POST的帮助者):

public IDaoRequestBean buildDaoRequest(final PostRequest request);

And for the helper of the GET : 对于GET的帮助者:

public IDaoRequestBean buildDaoRequest(final GetRequest request);

Using generics is not really needed. 确实不需要使用泛型。 You would need to have both classes implement a common interface, so you can call getCallerID / getUserID . 您将需要两个类都实现一个公共接口,因此可以调用getCallerID / getUserID But having them both implement a common interface, would remove the need for generics: 但是,让它们都实现一个公共接口,将消除对泛型的需求:

interface IRequest {
    String getCallerID();
    String getUserID();
}
/* Overcomplicated, with generics */
public <T extends IRequest> IDaoRequestBean buildDaoRequest(final T){...}

/* Using just the interface */
public IDaoRequestBean buildDaoRequest(final IRequest){...}

So you're pretty stuck with inheritance. 所以,你很坚持了继承。


Using an abstract class instead of an interface has the added benefit of not having to redeclare fields and getters. 使用abstract class而不是接口具有不必重新声明字段和获取器的额外好处。 With the limitation that you can't extend any other class. 由于不能扩展任何其他类的限制。

abstract class BaseRequest {
    private String callerId;
    private String userId;

    // Getters
}

class GetRequest extends BaseRequest {...}
class PostRequest extends BaseRequest {...}
/* Pretty much the same here... */
public IDaoRequestBean buildDaoRequest(final BaseRequest){...}

I believe inheritance would be the way to go. 我相信继承是必经之路。 If you end up having new requests, having generics could mean that you could pass a type of a request that possibly wouldn't match the implementation of a method unless they extend the same class, which would lead to inheritance, isn't it? 如果最终收到新的请求,则泛型可能意味着您可以传递一个请求的类型,该请求的类型可能与方法的实现不匹配,除非它们扩展了同一类,这会导致继承,不是吗? By having only requests of a type POST and GET's superclass, you limit it to the two of them. 通过仅拥有POST和GET的超类类型的请求,可以将其限制为两个。 Please correct me if I'm wrong. 如果我错了,请纠正我。

In my opinion, you should not have GetRequest as your request body for the get method call. 我认为,不应将GetRequest作为get方法调用的请求主体。 The get rest call should be based on Id(example: employees/id). 休息电话应基于ID(例如:employees / id)。 For some reasons if you are having an object in the request body, then follow the inheritance in your class hierarchy but be specific on your class type in both the rest and the helper method implementation methods because 由于某些原因,如果请求主体中有一个对象,则遵循类层次结构中的继承,但在其余类型和辅助方法实现方法中都应具体说明类类型,因为

  1. In the future, you may have to add a new common attribute so this model gives you flexibility. 将来,您可能必须添加一个新的common属性,以便该模型为您提供灵活性。

    abstract class AbstractRequest{ //Common attributes } 抽象类AbstractRequest {//公共属性}

    class GetRequest extends AbstractRequest{} 类GetRequest扩展AbstractRequest {}

    class PostRequest extends AbstractRequest{} PostRequest类扩展AbstractRequest {}

  2. Also in the rest model arguments and helper class method arguments, if you don't define the specific child type as parameters, another developer can call your helper class with any child type of the argument. 同样在其余模型参数和助手类方法参数中,如果您没有将特定的子类型定义为参数,则另一个开发人员可以使用任何子类型的参数来调用您的助手类。 This can break your functionality. 这可能会破坏您的功能。 So be specific on the argument type in the helper and rest methods. 因此,请具体说明helper和rest方法中的参数类型。

    GET -> method(GetRequest) GET-> method(GetRequest)

    POST -> method(PostRequest) POST-> method(PostRequest)

    public IDaoRequestBean buildDaoRequest(final PostRequest request); 公共IDaoRequestBean buildDaoRequest(最终PostRequest请求);

    public IDaoRequestBean buildDaoRequest(final GetRequest request); 公共IDaoRequestBean buildDaoRequest(最终GetRequest请求);

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

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