Template for a sequence of steps without a common interface

In my Java application, I got a method that performs a long sequence of steps (synchronously), where one step is the input for the next.

eg:

// Step 1
Map<String, SomeObject> objectsMap = someService.createObjectsMap();
if (!objectsMap.isEmpty()) {
    // Step 2
    AnotherObject anotherObject = anotherService.createAnotherObject(objectsMap);
    if (null != anotherObject) {
    // Step 3 that gets anotherObject as input and returns something else
    } else { // Step 2 failed
        // log and handle
    }
} else { // Step 1 failed
    // log and handle
}

And so I got this series of steps written in a series of if-else blocks. There is no common interface for steps, since each of them has its own signature. I looked at some others and tried to set up templates such as responsibility chain and team, but could not get a satisfied result.

Interestingly, is this ugly long if-else section a path or is there a template that can help make this series of steps cleaner and more scalable?

+5
3

, : ?

,

  • ?
  • ?
  • () ?

,

, . .

/**
 * Explain what step1 does.
 */
private void step1() {
    // Step 1
    Map<String, SomeObject> objectsMap = someService.createObjectsMap();
    if (!objectsMap.isEmpty()) {
        step2(objectsMap);
    } else { // Step 1 failed
        // log and handle
    }
}

/**
 * Explain what step2 does.
 */
private void step2(Map<String, SomeObject> objectsMap) {
    // Step 2
    final AnotherObject anotherObject = anotherService
            .createAnotherObject(objectsMap);
    if (null != anotherObject) {
        step3(anotherObject);
    } else { // Step 2 failed
        // log and handle
    }
}

/**
 * Explain what step3 does.
 */
private void step3(AnotherObject anotherObject) {
    // Step 3 that gets anotherObject as input and returns something
    // else
}

. , . , Javadoc. . Javadoc.

,

, (, - ), , , .

, API, .

. .

for (Step step : steps) {
    boolean executeNext = step.execute();
    if (!executeNext) {
        break;
    }
}

Step

public interface Step {
    boolean execute();
}

?

public static interface StepInput<T> {
    public T getInput();
}

. .

public abstract class InputOutputStep<T> implements Step,
        StepInput<T> {

    private T returnValue;

    protected void setReturnValue(T returnValue) {
        this.returnValue = returnValue;
    }

    public T getInput() {
        return returnValue;
    }
}

public class Step1 extends InputOutputStep<Map<String, SomeObject>> {

    private StepInput<Map<String, SomeObject>> stepInput;

    public Step1(StepInput<Map<String, SomeObject>> stepInput) {
        this.stepInput = stepInput;
    }

    public boolean execute() {
        boolean executeNext = false;

        Map<String, SomeObject> objectsMap = stepInput.getInput();
        if (!objectsMap.isEmpty()) {
            // Step 2
            setReturnValue(objectsMap);
            executeNext = true;
        } else { // Step 1 failed
            // log and handle
        }

        return executeNext;
    }
}

public class Step2 extends InputOutputStep<AnotherObject> {

    private StepInput<Map<String, SomeObject>> stepInput;
    private AnotherService anotherService;

    public Step2(AnotherService anotherService,
            StepInput<Map<String, SomeObject>> stepInput) {
        this.anotherService = anotherService;
        this.stepInput = stepInput;
    }

    public boolean execute() {
        boolean executeNext = false;

        Map<String, SomeObject> objectsMap = stepInput.getInput();
        AnotherObject anotherObject = anotherService
                .createAnotherObject(objectsMap);
        if (null != anotherObject) {
            setReturnValue(anotherObject);
            executeNext = true;
        } else { // Step 2 failed
            // log and handle
        }
        return executeNext;
    }
}

public class Step3 extends InputOutputStep<Void> {

    private StepInput<AnotherObject> stepInput;

    public Step3(StepInput<AnotherObject> stepInput) {
        this.stepInput = stepInput;
    }

    public boolean execute() {
        AnotherObject anotherObject = stepInput.getInput();
        setReturnValue(null);
        return false;
    }
}

Step1 step1 = new Step1(stepInput);
Step2 step2 = new Step2(anotherService, step1);
Step step3 = new Step3(step2);

Step[] steps = new Step[]{step1, step2, step3};

for (Step step : steps) {
    boolean executeNext = step.execute();
    if (!executeNext) {
        break;
    }
}
+6

- , - - . :

try {
    // Step 1
    Map<String, SomeObject> objectsMap = someService.createObjectsMap();
    if (objectsMap.isEmpty())
        throw new SomethingWentWrongException("Failed to get object map from service");

    // Step 2
    AnotherObject anotherObject = anotherService.createAnotherObject(objectsMap);
    if(anotherObject == null)
        throw new SomethingWentWrongException("Failed to create another object");

    // Step 3 that gets anotherObject as input and returns something else
} catch(SomethingWentWrongException e) {
    // log and handle
    e.printStackTrace();
}

someService.createObjectsMap anotherService.createAnotherObject , . :

try {
    Map<String, SomeObject> objectsMap = someService.createObjectsMap();
    AnotherObject anotherObject = anotherService.createAnotherObject(objectsMap);
    // Step 3 that gets anotherObject as input and returns something else
} catch(Exception e) {
    // log and handle
    e.printStackTrace();
}

( , Exception, )

0

:

  • Memento Pattern: memento . , . , 1 3, 1 . , , , . .

  • : IF-ELSE. , . . , ( ).

  • : - MVC. , - . - , - , CCTV. , , , .

,

-1

All Articles