можем ли мы оптимизировать приведенный ниже код с помощью универсальных

#java #generics

Вопрос:

У меня есть класс обслуживания, который выполняет 2 разных вызова другого API, который возвращает 2 разных объекта ответа. Для простоты пусть это будет показано, как показано ниже

 public class Service {

    public AddResponseWrapper add(Request request)  {

        final AddResponseWrapper addResponseWrapper = new AddResponseWrapper();

        try {
            final AddResponse addResponse = addApi.add(request);
            addResponseWrapper.setAddResponse(addResponse);

        } catch (final Exception e) {
            addResponseWrapper.setErrorDetails(convert(e));
        }
        return addResponseWrapper;
    }

     public DeleteResponseWrapper delete(Request request)  {

     final DeleteResponseWrapper deleteResponseWrapper = new DeleteResponseWrapper();

        try {
            final DeleteResponse deleteResponse = deleteApi.delete(request);
            deleteResponseWrapper.setDeleteResponse(deleteResponse);

        } catch (final Exception e) {
            deleteResponseWrapper.setErrorDetails(convert(e));
        }
        return deleteResponseWrapper;
    }
}
 

Аналогично, у меня есть эти 2 ниже созданных POJOs

 public class AddResponseWrapper {

    private AddResponse addResponse;

    private ErrorDetails errorDetails;

    public AddResponse getAddResponse() {
        return addResponse;
    }

    public void setAddResponse(final AddResponse addResponse) {
        this.addResponse = addResponse;
    }

    public ErrorDetails getErrorDetails() {
        return errorDetails;
    }

    public void setErrorDetails(final ErrorDetails errorDetails) {
        this.errorDetails = errorDetails;
    }

}


public class DeleteResponseWrapper {
    
        private DeleteResponse deleteResponse;
    
        private ErrorDetails errorDetails;
    
        public DeleteResponse getDeleteResponse() {
            return deleteResponse;
        }
    
        public void setDeleteResponse(final DeleteResponse deleteResponse) {
            this.deleteResponse = deleteResponse;
        }
    
        public ErrorDetails getErrorDetails() {
            return errorDetails;
        }
    
        public void setErrorDetails(final ErrorDetails errorDetails) {
            this.errorDetails = errorDetails;
        }
    
    }
 

AddResponseWrapper и DeleteResponseWrapper-это классы, которые я создал, в то время как классы AddResponse и DeleteResponse-это классы, которые я наследую от API, который я вызываю.

Теперь, если я сделаю еще 2 вызова APi, скажем, для операций вычитания и умножения, мне придется создать еще 2 класса POJO SubtractResponseWrapper и MultiplyResponseWrapper.

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

Комментарии:

1. Это не дженерики .. у вас есть ключ к разгадке в ваших словах — это операции… Поэтому у OperationResponseWrapper вас есть и getOperationResponse / setOperationResponse .. ваш ответ/Удаление ответа//Множественный ответ/и т. Д., Все они должны затем реализовать интерфейс OperationResponse — скажем, с помощью метода apply() — в котором есть код, который каждый из классов Add/Delete/etcResponse использует по-разному.

2. спасибо за ответ, но, как я уже упоминал, классы AddResponse/DeleteResponse//multipleResponse/ являются производными классами от генератора клиентов API Swagger, поэтому я не смог бы их редактировать.

3. В вашем вопросе нет никакого чванства, но, конечно, если вы ничего не можете изменить, то вы застряли. У вас определенно может быть оболочка<T>, однако без какой-либо наследственности вы получите оболочку<T><Объект>.

Ответ №1:

Попробуйте это — однако без какой-либо наследственности в ваших ответных объектах, возможно, это будет не намного лучше, чем ResponseWrapper<Object> .

 public class ResponseWrapper<T> {
    
        private T response;
    
        private ErrorDetails errorDetails;
    
        public T getResponse() {
            return response;
        }
    
        public void setResponse(final T response) {
            this.response = response;
        }
    
        public ErrorDetails getErrorDetails() {
            return errorDetails;
        }
    
        public void setErrorDetails(final ErrorDetails errorDetails) {
            this.errorDetails = errorDetails;
        }
    
    }
 

Тогда ваше служение становится —

 public class Service {

    public ResponseWrapper<AddResponse> add(Request request)  {

        final ResponseWrapper<AddResponse> addResponseWrapper = new ResponseWrapper<AddResponse>();

        try {
            final AddResponse addResponse = addApi.add(request);
            addResponseWrapper.setResponse(addResponse);

        } catch (final Exception e) {
            addResponseWrapper.setErrorDetails(convert(e));
        }
        return addResponseWrapper;
    }

     public ResponseWrapper<Delete> delete(Request request)  {

     final ResponseWrapper<Delete> deleteResponseWrapper = new ResponseWrapper<Delete>();

        try {
            final DeleteResponse deleteResponse = deleteApi.delete(request);
            deleteResponseWrapper.setResponse(deleteResponse);

        } catch (final Exception e) {
            deleteResponseWrapper.setErrorDetails(convert(e));
        }
        return deleteResponseWrapper;
    }
}
 

Без изменения класса API вы не сможете продвинуться дальше в упрощении.