java inheritance vs generics

时间:2016-07-20 11:28:54

标签: java generics inheritance

这里的小Java设计问题(重要的是它在JEE Web应用程序的上下文中)。

假设我有一个REST API,它有两个操作:GETPOST在同一个资源上。从那里开始,使用Jackson构建两个类来表示请求的输入字段。那些课程是不同的,因为请求'参数有所不同。

我们假设这两个类名为 GetRequest PostRequest

这两个类包含一组常见字段。以及属于每个类的字段集。例如:

public class GetRequest {

   // common fields
   private String callerId;

   private String userId;

   // non-common fields
   private boolean withLinkedServices;

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

对于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...
}

在我的应用程序的业务层中,我必须编写一个 helper 方法(对于每个REST操作),它将使用每个对象的公共字段填充另一个bean。对于GET和POST操作,此方法的实现完全相同。

唯一不同的是,在GET操作的情况下,我必须通过GetRequest类,对于POST,我必须通过PostRequest

所以我的问题是:

我应该使用数据模型并使用继承还是应该在我的帮助方法中使用泛型?哪一个更有意义,更有效,更适应应用程序的未来演变(例如,如果在该资源上添加了更多操作)?

我的方法的签名是(对于POST的帮助者):

public IDaoRequestBean buildDaoRequest(final PostRequest request);

对于GET的帮手:

public IDaoRequestBean buildDaoRequest(final GetRequest request);

3 个答案:

答案 0 :(得分:1)

不需要使用泛型。您需要让两个类都实现一个通用接口,因此您可以调用getCallerID / getUserID。但让他们都实现一个通用的接口,将消除对泛型的需求:

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

所以你很坚持继承。

使用abstract class而不是接口具有无需重新声明字段和getter的额外好处。由于您无法扩展任何其他类的限制。

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

答案 1 :(得分:0)

我相信继承将是最佳选择。如果你最终有了新的请求,那么使用泛型可能意味着你可以传递一种可能与方法的实现不匹配的请求,除非它们扩展同一个类,这会导致继承,不是吗?通过仅具有POST和GET类型的超类请求,您可以将其限制为两个。如果我错了,请纠正我。

答案 2 :(得分:0)

在我看来,你不应该将GetRequest作为get方法调用的请求体。 get rest调用应该基于Id(例如:employees / id)。 出于某些原因,如果您在请求正文中有一个对象,那么请遵循类层次结构中的继承,但在其余和辅助方法实现方法中都要特定于您的类类型,因为

  1. 将来,您可能需要添加新的公共属性,以便此模型为您提供灵活性。

    abstract class AbstractRequest { //常用属性 }

    类GetRequest扩展AbstractRequest {}

    类PostRequest扩展了AbstractRequest {}

  2. 同样在其余模型参数和辅助类方法参数中,如果您不将特定子类型定义为参数,则另一个开发人员可以使用该参数的任何子类型调用您的帮助程序类。这可能会破坏您的功能。所以请具体说明helper和rest方法中的参数类型。

    GET - &gt;方法(的GetRequest)

    POST - &gt;方法(PostRequest)

    public IDaoRequestBean buildDaoRequest(final PostRequest request);

    public IDaoRequestBean buildDaoRequest(final GetRequest request);