lundi 25 juillet 2022

Design pattern discussion - advantage of abstract class holding concrete classes and their instances

Its a very open ended question about a particular design, so hope people dont vote it down.

In my team's codebase, i see a pattern about API Error Codes (that are returned when someone invokes our API). We have an abstract class with bunch of private and public member variables. The abstract class itself have concrete classes inside it. And it also has instances of those concrete classes.

I am not sure whats the advantage of this design? Couldn't we just have an enum? Has anyone worked on any use case with similar design pattern (and can shed light on where it is useful and what are the advantages)?

Here is how the abstract class looks like (I have omitted detailed code for constructors etc to keep it short) -

public abstract class ApiErrorCodes{
    private static final int XMLRPC_UNKNOWN_EXCEPTION = -1;
    private final int xmlRpcErrorCode;
    private final String statusCode;
    private final String exceptionCode;
    private final AppVersion minExceptionSoapVersion;
    private final ApiErrorCodes fallbackExceptionCode;
    private final AppVersion minStatusSoapVersion;
    private final ApiErrorCodes fallbackStatusCode;
    private final Scope scope;
    private final HttpStatusCode httpStatusCode;
    private static List<ApiErrorCodes> ALL_CODES = new ArrayList<ApiErrorCodes>();
    

    public static List<ApiErrorCodes> getAllCodes(){ return ALL_CODES;}

    //constructor to populate above variables
    private ApiErrorCodes(int xmlRpcErrorCode, String statusCode, String exceptionCode,
        AppVersion minExceptionSoapVersion, ApiErrorCodes exceptionFallbackErrorCode, AppVersion minStatusSoapVersion,
        ApiErrorCodes statusFallbackCode, Scope scope, HttpStatusCode httpStatusCode){}

    //bunch of public getters to retrieve values of variables above. Skipping over them.

    //classes that extend the abstract class
    public static class ApiStatusCode extends ApiErrorCodes{ /*bunch of constructors that call super to populate variables*/}
    public static class ApiExceptionCode extends ApiErrorCodes {}
    public static class ApiStatusCodeAndExceptionCode extends ApiErrorCodes{}
    public static class XmlRpcErrorCode extends ApiErrorCodes{}

    //instances of above classes
    public static final ApiErrorCodes BAD_XML = new ApiStatusCodeAndExceptionCode(0, null, null HttpStatusCode.BAD_REQUEST);
    public static final ApiErrorCodes NULL_PARAMETER_LIST = new XmlRpcErrorCode(1000);
    public static final ApiErrorCodes API_CURRENTLY_DISABLED = new ApiExceptionCode(1007, "API_CURRENTLY_DISABLED", HttpStatusCode.FORBIDDEN);

}

and in rest of the code, we access specific error code by referencing them like this -

return(ApiErrorCodes.BAD_XML)

Aucun commentaire:

Enregistrer un commentaire