Progettazione di un oggetto di risposta unificato - java

0

Sto progettando un oggetto di risposta unificato per l'applicazione di servizi REST, in modo che il client si aspetti sempre la stessa struttura, sia che venga generata un'eccezione, che venga restituito uno stato semplice, una mappa di chiavi e valori o un DTO complesso. L'idea è che in qualsiasi dei casi di cui sopra, voglio avvolgere la risposta in un oggetto che contiene un messaggio, tempo di risposta e altre informazioni generali .. ecco cosa ho fatto, e voglio un feedback dagli esperti qui, se questo è l'approccio migliore, c'è un approccio migliore che segue un modello di progettazione noto per il problema, questo design ha uno svantaggio e se questo design segue uno dei modelli di design conosciuti:

@Data
public class StandardResponse{

public static int STATUS_RESPONSE = 1;
public static int DTO_RESPONSE = 2;
public static int MAP_RESPONSE = 3;
public static int SINGULAR_RESPONSE = 4;
public static int EXCEPTION_RESPONSE = 5;

protected Date responseTime;
protected String message;
protected int responseType;
protected Object containedObject;

public StandardResponse() {
    responseTime = new Date();
}

public StandardResponse(String message, Object containedObject, int responseType) {
    this();
    this.message = message;
    this.containedObject = containedObject;
    this.responseType = responseType;
}

public static StandardResponse createStandardResponse(int responseType, Object input) {
    return createStandardResponse(responseType, input, null);
}

public static StandardResponse createStandardResponse(int responseType, Object input, String message) {
    StandardResponse response = null;
    Object containedObject = null;
    if(STATUS_RESPONSE == responseType) {
        containedObject = new StatusResponseDTO((Boolean)input);
    }else if(DTO_RESPONSE == responseType) {
        containedObject =  input;
    }else if(MAP_RESPONSE == responseType) {
        containedObject =  input;
    }else if(SINGULAR_RESPONSE == responseType) {
        Map<String,Object> singularValue = new HashMap<String,Object>();
        singularValue.put("value", input);
        containedObject = singularValue;
    }else if(EXCEPTION_RESPONSE == responseType) {
        //TODO
    }
    response = new StandardResponse(message,containedObject,responseType);
    return response;
}

}

Perché non sono andato nel modo più semplice di creare una super classe StandardResponse ed ereditare tutti gli altri tipi da esso? perché in caso di restituzione di Map o Exception non sarò esteso StandardResponse

    
posta osama yaccoub 07.04.2018 - 05:01
fonte

2 risposte

2

Questo sembra un caso d'uso perfetto per i modelli generici o di classe.

public class StandardResponse<T> {
    private T message;

    public StandardResponse(T message, int responseCode) {
        this.message = message;
        // ...
    }

    public T getMessage() {
        return message;
    }
}

Ora le tue risposte possono essere adattate a qualsiasi cosa tu voglia:

try {
    BlogPost = new BlogPost(...);

    // Save to database

    return new StandardResponse<BlogPost>(blogPost, 200);
} catch (Exception ex) {
    return new StandardResponse<Exception>(ex, 500);
}

Con questo, puoi eseguire la sottolivello StandardResponse per chiarire ulteriormente il tuo codice e il suo intento:

public class ServerErrorResponse extends StandardResponse<Exception> {
    public ServerErrorResponse(Exception exception) {
        super(exception, 500);
    }
}

public class ResourceNotFoundResponse extends StandardResponse<String> {
    public ResourceNotFoundResponse(string message) {
        super(message, 404);
    }
}

public class SuccessResponse<T> extends StandardResponse<T> {
    public SuccessResponse(T message) {
        super(message, 200);
    }
}

E usarlo sembra più RESTful:

try {
    BlogPost postToEdit = // get from database

    if (postToEdit == null) {
        return new ResourceNotFoundResponse("Blog post not found");
    }

    // edit and save to DB

    return new SuccessResponse<BlogPost>(postToEdit);
} catch (Exception ex) {
    return new ServerErrorResponse(ex);
}
    
risposta data 07.04.2018 - 14:31
fonte
0

Nel complesso sembra ok, ma dato che hai postato qui per ottenere un feedback, ecco cosa di solito menziono nelle mie recensioni del codice.

  • la convenzione è che se dichiari costanti (considerando che le tue variabili sono in maiuscolo, presumo che siano costanti) dovrebbero essere dichiarate come 'statico finale'
  • Suggerirei di rendere private anche queste costanti
  • la classe ha una sorta di "metodo factory" (createStandardResponse), quindi la domanda è: hai bisogno di accedere ai tuoi costruttori dall'esterno della classe? Se non dichiari i tuoi costruttori privati (o protetti, guardando le variabili protette sembra che tu voglia estenderlo)
  • Risposta risposta standard = null; - è ridondante, puoi semplicemente fare restituire nuovo StandardResponse (...)
  • Sostituire più se / else se con l'istruzione switch renderà più leggibile
  • nuovo StatusResponseDTO (input (booleano)) - non sembra sicuro, forse vale la pena controllare l'instanceof prima del casting, o se possibile inviare l'input come String e quindi fare Boolean.valueOf (input )

  • E per favore, per favore, usa LocalDate invece di Date (si spera che sia Java 8):)

risposta data 16.04.2018 - 22:58
fonte

Leggi altre domande sui tag