2016-07-20 3 views
0

Небольшой вопрос проектирования Java здесь (для чего это важно в контексте веб-приложения JEE).java inheritance vs generics

Предположим, у меня есть REST API с двумя операциями: GET и POST на тех же ресурсах. Оттуда построены два класса Джексона, представляющие поля ввода запроса. Эти классы различаются, потому что параметры запросов немного отличаются.

Допустим, эти два класса называются 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... 
} 

В бизнес-уровне моего приложения, я должен кодировать вспомогательный метод (для каждой операции REST), который будет заполнить еще один компонент, используя общие поля каждого объекта. Реализация этого метода точно такая же для операций GET и POST.

Единственное, что меняется, - это то, что в случае операций GET я должен пройти класс GetRequest, а для POST я должен передать PostRequest.

Так что мой вопрос:

Должен ли я работать на модели данных и использовать наследование или я должен использовать генериков в моем хелперов методе? Какой из них будет иметь больше смысла и будет более эффективным и устойчивым к будущей эволюции приложения (в случае, если, например, добавлены дополнительные операции в эти ресурсы)?

Сигнатура моих методов (для помощника самотестирования):

public IDaoRequestBean buildDaoRequest(final PostRequest request); 

И помощнике ГЕТ:

public IDaoRequestBean buildDaoRequest(final GetRequest request); 
+0

чтения [это] (http://stackoverflow.com/questions/2642598/generics-vs-inheritance-when-no-collection-classes-are-involved) –

ответ

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 вместо интерфейса имеет дополнительное преимущество, не имея переобъявить поля и методы получения. С ограничением, что вы не можете расширить какой-либо другой класс.

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

Я считаю, наследство будет путь , Если у вас появятся новые запросы, наличие дженериков может означать, что вы могли бы передать тип запроса, который, возможно, не соответствовал реализации метода, если они не расширят тот же класс, что приведет к наследованию, не так ли? Имея только запросы типа POST и GET суперкласса, вы ограничиваете их двумя из них. Пожалуйста, поправьте меня, если я ошибаюсь.

0

На мой взгляд, у вас не должно быть GetRequest в качестве тела запроса для вызова метода get. Звонок для отдыха должен быть основан на Id (пример: employee/id). По некоторым причинам, если вы имеете объект в теле запроса, затем следуют наследования в вашей иерархии классов, но быть специфическими на в обоих остальных и вспомогательный метод методов реализации вашего типа класса, потому что

  1. В в будущем вам, возможно, придется добавить новый общий атрибут, чтобы эта модель давала вам гибкость.

    абстрактного класс AbstractRequest {атрибутов // Общие }

    класса GetRequest расширяет AbstractRequest {}

    класса PostRequest расширяет AbstractRequest {}

  2. Кроме того, в методе остальных моделей аргументов и вспомогательный класса аргументы, если вы не определяете конкретный дочерний тип как параметры, другой разработчик может вызвать ваш вспомогательный класс с любым дочерним типом аргумента. Это может нарушить вашу функциональность. Поэтому укажите тип аргумента в методах помощника и отдыха.

    GET -> метод (GetRequest)

    ПОСТ -> метод (PostRequest)

    общественных IDaoRequestBean buildDaoRequest (окончательный запрос PostRequest);

    public IDaoRequestBean buildDaoRequest (окончательный запрос GetRequest);