Search code examples
javainheritanceconstructorpolymorphismoverriding

What is a best practice to initialize an object at runtime in a method in java?


I have a java method:

public void method(JSONObject jsonRequest, String token, int size) {
    DataRequest request = new DataRequest(size);
    request.from(jsonRequest);

    if (StringUtils.isNotEmpty(token)) {
        request.setPageToken(token);
    }

    request.doSomething();
}

I want to make it a runtime decision on whether to use DataRequest or sub-class of DataRequest. One way to do that is the following:

public void method(JSONObject jsonRequest, String token, int size) {
    DataRequest request = buildDataRequest(jsonRequest, token, size);
    request.from(jsonRequest);

    if (StringUtils.isNotEmpty(token)) {
        request.setPageToken(token);
    }

    request.doSomething();
}

protected DataRequest buildDataRequest(JSONObject jsonRequest, String token, int size) {
    return new DataRequest(size);
}

Extracting the logic of creating the DataRequest object into another method and let the sub-classes override it.

Is there any better practice to achieve this?


Solution

  • You can create a functional interface creating the instance like (due to your parameter list you cannot use Supplier or (Bi)Function):

    @FunctionalInterface
    interface DataRequestFactory {
        DataRequest buildDataRequest(JSONObject jsonRequest, String token, int size);
    }
    

    Your class provides two constructors (maybe the default factory is not neccessary):

    public MyClass() {
        this((r, t, s) -> new DataRequest(s));
    }
    
    public MyClass(DataRequestFactory factory) {
        this.factory = factory;
    }
    

    Now you can call this.factory.buildDataRequest(JSONObject jsonRequest, String token, int size).