Java abstract out common code using java Functional expression

Viewed 99

There are 2 functions which have the same piece of code except one line.

public ResponseEntity<String> deleteJob(String jobName, String jobGroup) throws SchedulerException {
        JobKey jobKey = JobKey.jobKey(jobGroup, jobName);

        if (!schedulerFactoryBean.getScheduler().checkExists(jobKey))
            return new ResponseEntity<>(format(JOBNAME_JOBGROUP_COMMON_LOG.concat("does not exists"), jobName, jobGroup), HttpStatus.BAD_REQUEST);

        schedulerFactoryBean.getScheduler().deleteJob(jobKey);//Different Code line
        return new ResponseEntity<>(format(JOBNAME_JOBGROUP_COMMON_LOG.concat("deleted Successfully"), jobName, jobGroup), HttpStatus.OK);
    }

public ResponseEntity<String> resumeJob(String jobName, String jobGroup) throws SchedulerException {
        JobKey jobKey = JobKey.jobKey(jobGroup, jobName);

        if (!schedulerFactoryBean.getScheduler().checkExists(jobKey))
            return new ResponseEntity<>(format(JOBNAME_JOBGROUP_COMMON_LOG.concat("does not exists"), jobName, jobGroup), HttpStatus.BAD_REQUEST);

        schedulerFactoryBean.getScheduler().resumeJob(jobKey);//Different Code line
        return new ResponseEntity<>(format(JOBNAME_JOBGROUP_COMMON_LOG.concat("deleted Successfully"), jobName, jobGroup), HttpStatus.OK);
    }

I want to remove the duplicate code from both functions.

A straightforward solution would be to write a third common function and call it from both functions.However I was looking if there is a way ,I could use Lambda expression to pass the code functionality which is different.

Something like

public ResponseEntity<String> processJob(String jobName, String jobGroup, Function<String,String> jobfunction) {
        JobKey jobKey = JobKey.jobKey(jobGroup, jobName);

        if (!schedulerFactoryBean.getScheduler().checkExists(jobKey))
            return new ResponseEntity<>(format(JOBNAME_JOBGROUP_COMMON_LOG.concat("does not exists"), jobName, jobGroup), HttpStatus.BAD_REQUEST);

        jobfunction.apply(jobKey);//Apply the required code behaviour
        return new ResponseEntity<>(format(JOBNAME_JOBGROUP_COMMON_LOG.concat("deleted Successfully"), jobName, jobGroup), HttpStatus.OK);
    }

and then call the function as

processJob(jobName,jobGroup, <lambda expression with delete/resume function calling>)
3 Answers

How about simplifying with an enum define for all possible actions that the scheduler can perform

enum Action {
    DELETE, RESUME
}

and further passing down the awareness of how to process the job as a parameter --

public ResponseEntity<String> processJob(String jobName, String jobGroup, Action action) throws SchedulerException {
    JobKey jobKey = JobKey.jobKey(jobGroup, jobName);

    if (!schedulerFactoryBean.getScheduler().checkExists(jobKey))
        return new ResponseEntity<>(format(JOBNAME_JOBGROUP_COMMON_LOG.concat("does not exists"), jobName, jobGroup), HttpStatus.BAD_REQUEST);

    performSchedulerAction(schedulerFactoryBean.getScheduler(), jobKey, action);
    return new ResponseEntity<>(format(JOBNAME_JOBGROUP_COMMON_LOG.concat("deleted Successfully"), jobName, jobGroup), HttpStatus.OK);
}

which uses a private method such as

private void performSchedulerAction(Scheduler scheduler, JobKey jobKey, Action action) {
    switch (action) {
        case DELETE -> scheduler.deleteJob(jobKey);
        case RESUME -> scheduler.resumeJob(jobKey);
        default -> throw new IllegalArgumentException("no such case");
    }
}

Maybe not the best but that can be an approach, you can add the boolean to the parameter list to decide what you want to do

public ResponseEntity<String> processJob(String jobName, String jobGroup,boolean wantDelete) throws SchedulerException {
    JobKey jobKey = JobKey.jobKey(jobGroup, jobName);

    if (!schedulerFactoryBean.getScheduler().checkExists(jobKey))
        return new ResponseEntity<>(format(JOBNAME_JOBGROUP_COMMON_LOG.concat("does not exists"), jobName, jobGroup), HttpStatus.BAD_REQUEST);

    if(wantDelete)
    schedulerFactoryBean.getScheduler().deleteJob(jobKey);
    else 
       schedulerFactoryBean.getScheduler().resumeJob(jobKey);

    return new ResponseEntity<>(format(JOBNAME_JOBGROUP_COMMON_LOG.concat("deleted Successfully"), jobName, jobGroup), HttpStatus.OK);
}
Related